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
)
142 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
143 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
145 /* FIXME: add WriteAttributes */
147 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
148 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
150 hr
= IXmlWriter_WriteCData(writer
, L
"a");
151 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
153 hr
= IXmlWriter_WriteCharEntity(writer
, 'a');
154 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
156 hr
= IXmlWriter_WriteChars(writer
, L
"a", 1);
157 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
159 hr
= IXmlWriter_WriteComment(writer
, L
"a");
160 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
162 hr
= IXmlWriter_WriteDocType(writer
, L
"a", NULL
, NULL
, NULL
);
163 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
165 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, L
"a");
166 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
168 hr
= IXmlWriter_WriteEndDocument(writer
);
169 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
171 hr
= IXmlWriter_WriteEndElement(writer
);
172 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
174 hr
= IXmlWriter_WriteEntityRef(writer
, L
"a");
175 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
177 hr
= IXmlWriter_WriteFullEndElement(writer
);
178 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
180 hr
= IXmlWriter_WriteName(writer
, L
"a");
181 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
183 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
184 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
186 hr
= IXmlWriter_WriteNode(writer
, NULL
, FALSE
);
187 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
189 reader_set_input(reader
, "<a/>");
190 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
191 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
193 reader_set_input(reader
, "<a/>");
194 hr
= IXmlReader_Read(reader
, NULL
);
195 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
196 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
197 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
199 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
200 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
202 hr
= IXmlWriter_WriteQualifiedName(writer
, L
"a", NULL
);
203 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
205 hr
= IXmlWriter_WriteRaw(writer
, L
"a");
206 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
208 hr
= IXmlWriter_WriteRawChars(writer
, L
"a", 1);
209 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
211 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
212 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
214 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
215 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
217 hr
= IXmlWriter_WriteString(writer
, L
"a");
218 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
220 /* FIXME: add WriteSurrogateCharEntity */
222 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
223 ok(hr
== exp_hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, exp_hr
);
225 IXmlReader_Release(reader
);
228 static IStream
*writer_set_output(IXmlWriter
*writer
)
233 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
234 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
236 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
237 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
242 static HRESULT WINAPI
testoutput_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
244 if (IsEqualGUID(riid
, &IID_IUnknown
)) {
249 ok(0, "unknown riid=%s\n", wine_dbgstr_guid(riid
));
250 return E_NOINTERFACE
;
254 static ULONG WINAPI
testoutput_AddRef(IUnknown
*iface
)
259 static ULONG WINAPI
testoutput_Release(IUnknown
*iface
)
264 static const IUnknownVtbl testoutputvtbl
= {
265 testoutput_QueryInterface
,
270 static IUnknown testoutput
= { &testoutputvtbl
};
272 static HRESULT WINAPI
teststream_QueryInterface(ISequentialStream
*iface
, REFIID riid
, void **obj
)
274 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_ISequentialStream
))
281 return E_NOINTERFACE
;
284 static ULONG WINAPI
teststream_AddRef(ISequentialStream
*iface
)
289 static ULONG WINAPI
teststream_Release(ISequentialStream
*iface
)
294 static HRESULT WINAPI
teststream_Read(ISequentialStream
*iface
, void *pv
, ULONG cb
, ULONG
*pread
)
296 ok(0, "unexpected call\n");
300 static ULONG g_write_len
;
301 static HRESULT WINAPI
teststream_Write(ISequentialStream
*iface
, const void *pv
, ULONG cb
, ULONG
*written
)
308 static const ISequentialStreamVtbl teststreamvtbl
=
310 teststream_QueryInterface
,
317 static ISequentialStream teststream
= { &teststreamvtbl
};
319 static void test_writer_create(void)
329 CreateXmlWriter(&IID_IXmlWriter
, NULL
, NULL
);
330 CreateXmlWriter(NULL
, (void**)&writer
, NULL
);
333 hr
= CreateXmlWriter(&IID_IStream
, (void **)&unk
, NULL
);
334 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#lx.\n", hr
);
336 hr
= CreateXmlWriter(&IID_IUnknown
, (void **)&unk
, NULL
);
337 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
338 hr
= IUnknown_QueryInterface(unk
, &IID_IXmlWriter
, (void **)&writer
);
339 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
340 ok(unk
== (IUnknown
*)writer
, "unexpected interface pointer\n");
341 IUnknown_Release(unk
);
342 IXmlWriter_Release(writer
);
344 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
345 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
347 /* check default properties values */
349 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ByteOrderMark
, &value
);
350 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
351 ok(value
== TRUE
, "got %Id.\n", value
);
354 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_Indent
, &value
);
355 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
356 ok(value
== FALSE
, "got %Id.\n", value
);
359 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_OmitXmlDeclaration
, &value
);
360 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
361 ok(value
== FALSE
, "got %Id.\n", value
);
363 value
= XmlConformanceLevel_Auto
;
364 hr
= IXmlWriter_GetProperty(writer
, XmlWriterProperty_ConformanceLevel
, &value
);
365 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
366 ok(value
== XmlConformanceLevel_Document
, "got %Id.\n", value
);
368 IXmlWriter_Release(writer
);
371 static void test_invalid_output_encoding(IXmlWriter
*writer
, IUnknown
*output
)
376 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
377 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
379 hr
= IXmlWriter_SetOutput(writer
, output
);
380 ok(hr
== S_OK
, "Failed to set output, hr %#lx.\n", hr
);
382 /* TODO: WriteAttributes */
384 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
385 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
387 hr
= IXmlWriter_WriteCData(writer
, L
"a");
388 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
390 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
391 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
393 hr
= IXmlWriter_WriteChars(writer
, L
"a", 1);
394 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
396 hr
= IXmlWriter_WriteComment(writer
, L
"a");
397 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
399 hr
= IXmlWriter_WriteDocType(writer
, L
"a", NULL
, NULL
, NULL
);
400 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
402 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, NULL
);
403 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
405 hr
= IXmlWriter_WriteEndDocument(writer
);
406 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
408 hr
= IXmlWriter_WriteEndElement(writer
);
409 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
411 hr
= IXmlWriter_WriteEntityRef(writer
, L
"a");
412 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
414 hr
= IXmlWriter_WriteFullEndElement(writer
);
415 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
417 hr
= IXmlWriter_WriteName(writer
, L
"a");
418 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
420 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
421 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
423 reader_set_input(reader
, "<a/>");
424 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
425 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
427 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
428 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
430 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
431 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
433 hr
= IXmlWriter_WriteQualifiedName(writer
, L
"a", NULL
);
434 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
436 hr
= IXmlWriter_WriteRaw(writer
, L
"a");
437 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
439 hr
= IXmlWriter_WriteRawChars(writer
, L
"a", 1);
440 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
442 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
443 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
445 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
446 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
448 hr
= IXmlWriter_WriteString(writer
, L
"a");
449 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
451 /* TODO: WriteSurrogateCharEntity */
453 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
454 ok(hr
== MX_E_ENCODING
, "Unexpected hr %#lx.\n", hr
);
456 hr
= IXmlWriter_Flush(writer
);
457 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
459 IXmlReader_Release(reader
);
462 static void test_writeroutput(void)
464 static const WCHAR utf16_outputW
[] = {0xfeff,'<','a'};
465 IXmlWriterOutput
*output
;
472 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, NULL
, &output
);
473 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
474 EXPECT_REF(output
, 1);
475 IUnknown_Release(output
);
477 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, L
"utf-16", &output
);
478 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
480 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
481 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
483 ok(unk
!= NULL
&& unk
!= output
, "got %p, output %p\n", unk
, output
);
484 EXPECT_REF(output
, 2);
485 /* releasing 'unk' crashes on native */
486 IUnknown_Release(output
);
487 EXPECT_REF(output
, 1);
488 IUnknown_Release(output
);
491 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, ~0u, &output
);
492 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
493 IUnknown_Release(output
);
495 hr
= CreateXmlWriterOutputWithEncodingCodePage(&testoutput
, NULL
, CP_UTF8
, &output
);
496 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
498 hr
= IUnknown_QueryInterface(output
, &IID_IXmlWriterOutput
, (void**)&unk
);
499 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
500 ok(unk
!= NULL
, "got %p\n", unk
);
501 /* releasing 'unk' crashes on native */
502 IUnknown_Release(output
);
503 IUnknown_Release(output
);
505 /* create with us-ascii */
507 hr
= CreateXmlWriterOutputWithEncodingName(&testoutput
, NULL
, L
"us-ascii", &output
);
508 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
509 IUnknown_Release(output
);
511 /* Output with codepage 1200. */
512 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
513 ok(hr
== S_OK
, "Failed to create writer, hr %#lx.\n", hr
);
515 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
516 ok(hr
== S_OK
, "Failed to create stream, hr %#lx.\n", hr
);
518 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, 1200, &output
);
519 ok(hr
== S_OK
, "Failed to create writer output, hr %#lx.\n", hr
);
521 hr
= IXmlWriter_SetOutput(writer
, output
);
522 ok(hr
== S_OK
, "Failed to set writer output, hr %#lx.\n", hr
);
524 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
525 ok(hr
== S_OK
, "Write failed, hr %#lx.\n", hr
);
527 hr
= IXmlWriter_Flush(writer
);
528 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
530 CHECK_OUTPUT_RAW(stream
, utf16_outputW
, sizeof(utf16_outputW
));
532 IStream_Release(stream
);
533 IUnknown_Release(output
);
535 /* Create output with meaningless code page value. */
536 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
537 ok(hr
== S_OK
, "Failed to create stream, hr %#lx.\n", hr
);
540 hr
= CreateXmlWriterOutputWithEncodingCodePage((IUnknown
*)stream
, NULL
, ~0u, &output
);
541 ok(hr
== S_OK
, "Failed to create writer output, hr %#lx.\n", hr
);
543 test_invalid_output_encoding(writer
, output
);
544 CHECK_OUTPUT(stream
, "");
546 IStream_Release(stream
);
547 IUnknown_Release(output
);
549 /* Same, with invalid encoding name. */
550 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
551 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
554 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"dummy", &output
);
555 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
557 test_invalid_output_encoding(writer
, output
);
558 CHECK_OUTPUT(stream
, "");
560 IStream_Release(stream
);
561 IUnknown_Release(output
);
563 IXmlWriter_Release(writer
);
566 static void test_writestartdocument(void)
568 static const char fullprolog
[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
569 static const char *prologversion2
= "<?xml version=\"1.0\" encoding=\"uS-asCii\"?>";
570 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
571 IXmlWriterOutput
*output
;
576 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
577 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
580 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
581 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
583 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
584 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
586 hr
= IXmlWriter_Flush(writer
);
587 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
589 stream
= writer_set_output(writer
);
591 /* nothing written yet */
592 hr
= IXmlWriter_Flush(writer
);
593 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
595 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
596 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
598 hr
= IXmlWriter_Flush(writer
);
599 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
601 CHECK_OUTPUT(stream
, fullprolog
);
604 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
605 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
606 IStream_Release(stream
);
608 /* now add PI manually, and try to start a document */
609 stream
= writer_set_output(writer
);
611 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
612 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
614 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
615 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
617 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
618 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
620 /* another attempt to add 'xml' PI */
621 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
622 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
624 hr
= IXmlWriter_Flush(writer
);
625 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
627 CHECK_OUTPUT(stream
, prologversion
);
629 IStream_Release(stream
);
630 IXmlWriter_Release(writer
);
632 /* create with us-ascii */
633 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
634 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
637 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"uS-asCii", &output
);
638 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
640 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
641 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
643 hr
= IXmlWriter_SetOutput(writer
, output
);
644 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
646 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
647 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
649 hr
= IXmlWriter_Flush(writer
);
650 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
652 CHECK_OUTPUT(stream
, prologversion2
);
654 IStream_Release(stream
);
655 IXmlWriter_Release(writer
);
656 IUnknown_Release(output
);
659 static void test_flush(void)
664 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
665 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
667 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)&teststream
);
668 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
670 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
671 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
674 hr
= IXmlWriter_Flush(writer
);
675 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
676 ok(g_write_len
> 0, "Unexpected length %lu.\n", g_write_len
);
679 hr
= IXmlWriter_Flush(writer
);
680 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
681 ok(g_write_len
== 0, "Unexpected length %lu.\n", g_write_len
);
683 /* Release() flushes too */
685 IXmlWriter_Release(writer
);
686 ok(g_write_len
== 0, "Unexpected length %lu.\n", g_write_len
);
689 static void test_omitxmldeclaration(void)
691 static const char prologversion
[] = "<?xml version=\"1.0\"?>";
698 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
699 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
701 stream
= writer_set_output(writer
);
703 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
705 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
706 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
708 hr
= IXmlWriter_Flush(writer
);
709 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
711 hr
= GetHGlobalFromStream(stream
, &hglobal
);
712 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
714 ptr
= GlobalLock(hglobal
);
715 ok(!ptr
, "got %p\n", ptr
);
716 GlobalUnlock(hglobal
);
719 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
720 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
722 IStream_Release(stream
);
724 /* now add PI manually, and try to start a document */
725 stream
= writer_set_output(writer
);
727 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
728 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
730 hr
= IXmlWriter_Flush(writer
);
731 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
733 CHECK_OUTPUT(stream
, prologversion
);
735 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
736 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
738 hr
= IXmlWriter_Flush(writer
);
739 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
741 CHECK_OUTPUT(stream
, prologversion
);
743 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
744 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
746 hr
= IXmlWriter_Flush(writer
);
747 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
749 CHECK_OUTPUT(stream
, prologversion
);
751 /* another attempt to add 'xml' PI */
752 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
753 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
755 hr
= IXmlWriter_Flush(writer
);
756 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
758 IStream_Release(stream
);
759 IXmlWriter_Release(writer
);
762 static void test_bom(void)
764 static const WCHAR piW
[] = {0xfeff,'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>'};
765 static const WCHAR aopenW
[] = {0xfeff,'<','a'};
766 static const WCHAR afullW
[] = {0xfeff,'<','a',' ','/','>'};
767 static const WCHAR bomW
[] = {0xfeff};
768 IXmlWriterOutput
*output
;
774 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
775 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
777 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
778 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
780 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
781 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
783 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
785 hr
= IXmlWriter_SetOutput(writer
, output
);
786 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
788 /* BOM is on by default */
789 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
790 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
792 hr
= IXmlWriter_Flush(writer
);
793 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
795 CHECK_OUTPUT_RAW(stream
, bomW
, sizeof(bomW
));
797 IStream_Release(stream
);
798 IUnknown_Release(output
);
801 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
802 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
804 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
805 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
807 hr
= IXmlWriter_SetOutput(writer
, output
);
808 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
810 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"xml", L
"version=\"1.0\"");
811 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
813 hr
= IXmlWriter_Flush(writer
);
814 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
816 CHECK_OUTPUT_RAW(stream
, piW
, sizeof(piW
));
818 IUnknown_Release(output
);
819 IStream_Release(stream
);
821 /* start with element */
822 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
823 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
825 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
826 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
828 hr
= IXmlWriter_SetOutput(writer
, output
);
829 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
831 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
832 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
834 hr
= IXmlWriter_Flush(writer
);
835 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
837 CHECK_OUTPUT_RAW(stream
, aopenW
, sizeof(aopenW
));
839 IUnknown_Release(output
);
840 IStream_Release(stream
);
842 /* WriteElementString */
843 hr
= CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
844 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
846 hr
= CreateXmlWriterOutputWithEncodingName((IUnknown
*)stream
, NULL
, L
"utf-16", &output
);
847 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
849 hr
= IXmlWriter_SetOutput(writer
, output
);
850 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
852 writer_set_property(writer
, XmlWriterProperty_Indent
);
854 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, NULL
);
855 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
857 hr
= IXmlWriter_Flush(writer
);
858 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
860 hr
= GetHGlobalFromStream(stream
, &hglobal
);
861 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
863 CHECK_OUTPUT_RAW(stream
, afullW
, sizeof(afullW
));
865 IUnknown_Release(output
);
866 IStream_Release(stream
);
868 IXmlWriter_Release(writer
);
871 static void test_WriteStartElement(void)
879 const char *output_partial
;
884 start_element_tests
[] =
886 { L
"prefix", L
"local", L
"uri", "<prefix:local xmlns:prefix=\"uri\" />", "<prefix:local" },
887 { NULL
, L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
888 { L
"", L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
889 { L
"", L
"local", L
"uri", "<local xmlns=\"uri\" />", "<local" },
890 { NULL
, L
"local", NULL
, "<local />", "<local" },
891 { NULL
, L
"local", L
"", "<local />", "<local" },
893 { L
"prefix", NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
894 { NULL
, NULL
, L
"uri", NULL
, NULL
, E_INVALIDARG
},
895 { NULL
, NULL
, NULL
, NULL
, NULL
, E_INVALIDARG
},
896 { NULL
, L
"prefix:local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
897 { L
"pre:fix", L
"local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
898 { NULL
, L
":local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
899 { L
":", L
"local", L
"uri", NULL
, NULL
, WC_E_NAMECHARACTER
},
900 { NULL
, L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, NULL
, WR_E_XMLNSPREFIXDECLARATION
},
901 { L
"prefix", L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, NULL
, WR_E_XMLNSURIDECLARATION
},
908 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
909 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
911 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
912 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
914 stream
= writer_set_output(writer
);
916 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
917 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
919 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
920 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
922 hr
= IXmlWriter_Flush(writer
);
923 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
925 CHECK_OUTPUT(stream
, "<a");
927 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
928 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
930 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, NULL
, NULL
);
931 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
933 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"a", L
"a");
934 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
936 IStream_Release(stream
);
937 IXmlWriter_Release(writer
);
939 /* WriteElementString */
940 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
941 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
943 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
944 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
946 stream
= writer_set_output(writer
);
948 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix", L
"a", L
"uri");
949 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
951 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
952 ok(hr
== S_OK
, "Failed to write element string, hr %#lx.\n", hr
);
954 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"c", NULL
, NULL
);
955 ok(hr
== S_OK
, "Failed to write element string, hr %#lx.\n", hr
);
957 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"d", L
"uri");
958 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
960 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"e", L
"uri");
961 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
963 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix2", L
"f", L
"uri");
964 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
966 hr
= IXmlWriter_Flush(writer
);
967 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
970 "<prefix:a xmlns:prefix=\"uri\">"
977 IStream_Release(stream
);
979 /* WriteStartElement */
980 for (i
= 0; i
< ARRAY_SIZE(start_element_tests
); ++i
)
982 stream
= writer_set_output(writer
);
984 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
986 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
987 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
989 hr
= IXmlWriter_WriteStartElement(writer
, start_element_tests
[i
].prefix
, start_element_tests
[i
].local
,
990 start_element_tests
[i
].uri
);
991 ok(hr
== start_element_tests
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
993 if (SUCCEEDED(start_element_tests
[i
].hr
))
995 hr
= IXmlWriter_Flush(writer
);
996 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
998 check_output(stream
, start_element_tests
[i
].output_partial
, start_element_tests
[i
].todo_partial
, __LINE__
);
1000 hr
= IXmlWriter_WriteEndDocument(writer
);
1001 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
1003 hr
= IXmlWriter_Flush(writer
);
1004 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1006 check_output(stream
, start_element_tests
[i
].output
, start_element_tests
[i
].todo
, __LINE__
);
1009 IStream_Release(stream
);
1012 IXmlWriter_Release(writer
);
1015 static void test_WriteElementString(void)
1019 const WCHAR
*prefix
;
1027 element_string_tests
[] =
1029 { L
"prefix", L
"local", L
"uri", L
"value", "<prefix:local xmlns:prefix=\"uri\">value</prefix:local>" },
1030 { NULL
, L
"local", L
"uri", L
"value", "<local xmlns=\"uri\">value</local>" },
1031 { L
"", L
"local", L
"uri", L
"value", "<local xmlns=\"uri\">value</local>" },
1032 { L
"prefix", L
"local", L
"uri", NULL
, "<prefix:local xmlns:prefix=\"uri\" />" },
1033 { NULL
, L
"local", L
"uri", NULL
, "<local xmlns=\"uri\" />" },
1034 { L
"", L
"local", L
"uri", NULL
, "<local xmlns=\"uri\" />" },
1035 { NULL
, L
"local", NULL
, NULL
, "<local />" },
1036 { L
"prefix", L
"local", L
"uri", L
"", "<prefix:local xmlns:prefix=\"uri\"></prefix:local>" },
1037 { NULL
, L
"local", L
"uri", L
"", "<local xmlns=\"uri\"></local>" },
1038 { L
"", L
"local", L
"uri", L
"", "<local xmlns=\"uri\"></local>" },
1039 { NULL
, L
"local", NULL
, L
"", "<local></local>" },
1040 { L
"", L
"local", L
"http://www.w3.org/2000/xmlns/", NULL
, "<local xmlns=\"http://www.w3.org/2000/xmlns/\" />" },
1042 { L
"prefix", NULL
, NULL
, L
"value", NULL
, E_INVALIDARG
},
1043 { NULL
, NULL
, L
"uri", L
"value", NULL
, E_INVALIDARG
},
1044 { NULL
, NULL
, NULL
, L
"value", NULL
, E_INVALIDARG
},
1045 { NULL
, L
"prefix:local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1046 { NULL
, L
":local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1047 { L
":", L
"local", L
"uri", L
"value", NULL
, WC_E_NAMECHARACTER
},
1048 { L
"prefix", L
"local", NULL
, L
"value", NULL
, WR_E_NSPREFIXWITHEMPTYNSURI
},
1049 { L
"prefix", L
"local", L
"", L
"value", NULL
, WR_E_NSPREFIXWITHEMPTYNSURI
},
1050 { NULL
, L
"local", L
"http://www.w3.org/2000/xmlns/", L
"value", NULL
, WR_E_XMLNSPREFIXDECLARATION
},
1051 { L
"prefix", L
"local", L
"http://www.w3.org/2000/xmlns/", L
"value", NULL
, WR_E_XMLNSURIDECLARATION
},
1058 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1059 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1061 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
1062 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1064 stream
= writer_set_output(writer
);
1066 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1067 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1069 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, L
"value");
1070 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1072 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1073 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1075 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"b", L
"uri", NULL
);
1076 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1078 hr
= IXmlWriter_WriteStartElement(writer
, L
"prefix", L
"c", L
"uri");
1079 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1081 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"d", NULL
, NULL
);
1082 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1084 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix2", L
"d", L
"uri", NULL
);
1085 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1087 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"e", L
"uri", NULL
);
1088 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1090 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"f", L
"uri2", NULL
);
1091 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1093 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"g", L
"uri3", NULL
);
1094 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1096 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix", L
"h", NULL
, NULL
);
1097 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1099 hr
= IXmlWriter_WriteElementString(writer
, L
"prefix_i", L
"i", NULL
, NULL
);
1100 ok(hr
== WR_E_NSPREFIXWITHEMPTYNSURI
, "Failed to write element, hr %#lx.\n", hr
);
1102 hr
= IXmlWriter_WriteElementString(writer
, L
"", L
"j", L
"uri", NULL
);
1103 ok(hr
== S_OK
, "Failed to write element, hr %#lx.\n", hr
);
1105 hr
= IXmlWriter_Flush(writer
);
1106 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1108 CHECK_OUTPUT(stream
,
1109 "<a><b>value</b><b />"
1110 "<prefix:b xmlns:prefix=\"uri\" />"
1111 "<prefix:c xmlns:prefix=\"uri\">"
1113 "<prefix2:d xmlns:prefix2=\"uri\" />"
1115 "<prefix:f xmlns:prefix=\"uri2\" />"
1116 "<g xmlns=\"uri3\" />"
1118 "<j xmlns=\"uri\" />");
1120 IStream_Release(stream
);
1122 for (i
= 0; i
< ARRAY_SIZE(element_string_tests
); ++i
)
1124 stream
= writer_set_output(writer
);
1126 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1128 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1129 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
1131 hr
= IXmlWriter_WriteElementString(writer
, element_string_tests
[i
].prefix
, element_string_tests
[i
].local
,
1132 element_string_tests
[i
].uri
, element_string_tests
[i
].value
);
1133 ok(hr
== element_string_tests
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
1135 if (SUCCEEDED(element_string_tests
[i
].hr
))
1137 hr
= IXmlWriter_Flush(writer
);
1138 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1140 check_output(stream
, element_string_tests
[i
].output
, element_string_tests
[i
].todo
, __LINE__
);
1142 hr
= IXmlWriter_WriteEndDocument(writer
);
1143 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
1145 hr
= IXmlWriter_Flush(writer
);
1146 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1148 check_output(stream
, element_string_tests
[i
].output
, element_string_tests
[i
].todo
, __LINE__
);
1151 IStream_Release(stream
);
1154 IXmlWriter_Release(writer
);
1157 static void test_WriteEndElement(void)
1163 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1164 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1166 stream
= writer_set_output(writer
);
1168 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1169 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1171 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1172 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1174 hr
= IXmlWriter_WriteEndElement(writer
);
1175 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1177 hr
= IXmlWriter_WriteEndElement(writer
);
1178 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1180 hr
= IXmlWriter_Flush(writer
);
1181 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1183 CHECK_OUTPUT(stream
, "<a><b /></a>");
1185 IXmlWriter_Release(writer
);
1186 IStream_Release(stream
);
1189 static void test_writeenddocument(void)
1197 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1198 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1200 hr
= IXmlWriter_WriteEndDocument(writer
);
1201 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1203 stream
= writer_set_output(writer
);
1205 /* WriteEndDocument resets it to initial state */
1206 hr
= IXmlWriter_WriteEndDocument(writer
);
1207 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1209 hr
= IXmlWriter_WriteEndDocument(writer
);
1210 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1212 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1213 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1215 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1216 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1218 hr
= IXmlWriter_SetOutput(writer
, (IUnknown
*)stream
);
1219 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1221 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1222 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1224 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1225 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1227 hr
= IXmlWriter_WriteEndDocument(writer
);
1228 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1230 hr
= GetHGlobalFromStream(stream
, &hglobal
);
1231 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1233 ptr
= GlobalLock(hglobal
);
1234 ok(ptr
== NULL
, "got %p\n", ptr
);
1236 /* we still need to flush manually, WriteEndDocument doesn't do that */
1237 hr
= IXmlWriter_Flush(writer
);
1238 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1240 CHECK_OUTPUT(stream
, "<a><b /></a>");
1242 IXmlWriter_Release(writer
);
1243 IStream_Release(stream
);
1246 static void test_WriteComment(void)
1252 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1253 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1255 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1257 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1258 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1260 stream
= writer_set_output(writer
);
1262 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1263 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1265 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1266 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1268 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1269 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1271 hr
= IXmlWriter_WriteComment(writer
, L
"a");
1272 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1274 hr
= IXmlWriter_WriteComment(writer
, NULL
);
1275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1277 hr
= IXmlWriter_WriteComment(writer
, L
"-->");
1278 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1280 hr
= IXmlWriter_Flush(writer
);
1281 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1283 CHECK_OUTPUT(stream
, "<!--a--><b><!--a--><!----><!--- ->-->");
1285 IXmlWriter_Release(writer
);
1286 IStream_Release(stream
);
1289 static void test_WriteCData(void)
1295 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1296 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1298 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1300 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1301 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1303 stream
= writer_set_output(writer
);
1305 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1306 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1308 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1309 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1311 hr
= IXmlWriter_WriteCData(writer
, NULL
);
1312 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1314 hr
= IXmlWriter_WriteCData(writer
, L
"]]>");
1315 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1317 hr
= IXmlWriter_WriteCData(writer
, L
"a]]>b");
1318 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1320 hr
= IXmlWriter_Flush(writer
);
1321 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1323 CHECK_OUTPUT(stream
,
1332 IXmlWriter_Release(writer
);
1333 IStream_Release(stream
);
1336 static void test_WriteRaw(void)
1338 static const WCHAR rawW
[] = L
"a<:";
1343 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1344 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1346 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1347 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1349 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1350 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1352 stream
= writer_set_output(writer
);
1354 hr
= IXmlWriter_WriteRaw(writer
, NULL
);
1355 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1357 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1358 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1360 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1361 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1363 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1364 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1366 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1367 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1369 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"a", NULL
, L
"a");
1370 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1372 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Yes
);
1373 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1375 hr
= IXmlWriter_WriteComment(writer
, rawW
);
1376 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1378 hr
= IXmlWriter_WriteEndDocument(writer
);
1379 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1381 hr
= IXmlWriter_WriteRaw(writer
, rawW
);
1382 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1384 hr
= IXmlWriter_Flush(writer
);
1385 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1386 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>a<:a<:<!--a<:-->a<:<a>a</a>");
1387 IStream_Release(stream
);
1389 /* With open element. */
1390 stream
= writer_set_output(writer
);
1392 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
1393 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1394 hr
= IXmlWriter_WriteRaw(writer
, L
"text");
1395 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1397 hr
= IXmlWriter_Flush(writer
);
1398 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1399 CHECK_OUTPUT(stream
, "<w>text");
1400 IStream_Release(stream
);
1402 IXmlWriter_Release(writer
);
1405 static void test_writer_state(void)
1411 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1412 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1415 check_writer_state(writer
, E_UNEXPECTED
);
1417 /* set output and call 'wrong' method, WriteEndElement */
1418 stream
= writer_set_output(writer
);
1420 hr
= IXmlWriter_WriteEndElement(writer
);
1421 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1423 check_writer_state(writer
, WR_E_INVALIDACTION
);
1424 IStream_Release(stream
);
1426 /* WriteAttributeString */
1427 stream
= writer_set_output(writer
);
1429 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"a");
1430 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1432 check_writer_state(writer
, WR_E_INVALIDACTION
);
1433 IStream_Release(stream
);
1435 /* WriteEndDocument */
1436 stream
= writer_set_output(writer
);
1438 hr
= IXmlWriter_WriteEndDocument(writer
);
1439 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1441 check_writer_state(writer
, WR_E_INVALIDACTION
);
1442 IStream_Release(stream
);
1444 /* WriteFullEndElement */
1445 stream
= writer_set_output(writer
);
1447 hr
= IXmlWriter_WriteFullEndElement(writer
);
1448 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1450 check_writer_state(writer
, WR_E_INVALIDACTION
);
1451 IStream_Release(stream
);
1454 stream
= writer_set_output(writer
);
1456 hr
= IXmlWriter_WriteCData(writer
, L
"a");
1457 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1459 check_writer_state(writer
, WR_E_INVALIDACTION
);
1460 IStream_Release(stream
);
1463 stream
= writer_set_output(writer
);
1465 hr
= IXmlWriter_WriteName(writer
, L
"a");
1466 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1468 check_writer_state(writer
, WR_E_INVALIDACTION
);
1469 IStream_Release(stream
);
1472 stream
= writer_set_output(writer
);
1474 hr
= IXmlWriter_WriteNmToken(writer
, L
"a");
1475 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1477 check_writer_state(writer
, WR_E_INVALIDACTION
);
1478 IStream_Release(stream
);
1481 stream
= writer_set_output(writer
);
1483 hr
= IXmlWriter_WriteString(writer
, L
"a");
1484 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
1486 check_writer_state(writer
, WR_E_INVALIDACTION
);
1487 IStream_Release(stream
);
1489 IXmlWriter_Release(writer
);
1492 static void test_indentation(void)
1498 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1499 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1501 stream
= writer_set_output(writer
);
1503 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1504 writer_set_property(writer
, XmlWriterProperty_Indent
);
1506 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1507 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1509 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1510 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1512 hr
= IXmlWriter_WriteComment(writer
, L
"comment");
1513 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1515 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1516 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1518 hr
= IXmlWriter_WriteEndDocument(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
,
1526 " <!--comment-->\r\n"
1530 IStream_Release(stream
);
1532 /* WriteElementString */
1533 stream
= writer_set_output(writer
);
1535 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1536 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1538 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1539 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1541 hr
= IXmlWriter_WriteElementString(writer
, NULL
, L
"b", NULL
, NULL
);
1542 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1544 hr
= IXmlWriter_WriteEndElement(writer
);
1545 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1547 hr
= IXmlWriter_Flush(writer
);
1548 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1550 CHECK_OUTPUT(stream
,
1556 IStream_Release(stream
);
1558 IXmlWriter_Release(writer
);
1561 static void test_WriteAttributeString(void)
1565 const WCHAR
*prefix
;
1570 const char *output_partial
;
1578 { NULL
, L
"a", NULL
, L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1579 { L
"", L
"a", NULL
, L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1580 { NULL
, L
"a", L
"", L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1581 { L
"", L
"a", L
"", L
"b", "<e a=\"b\" />", "<e a=\"b\"" },
1582 { L
"prefix", L
"local", L
"uri", L
"b", "<e prefix:local=\"b\" xmlns:prefix=\"uri\" />", "<e prefix:local=\"b\"" },
1583 { NULL
, L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e xmlns:a=\"defuri\" />", "<e xmlns:a=\"defuri\"" },
1584 { L
"xmlns", L
"a", NULL
, L
"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1585 { L
"xmlns", L
"a", L
"", L
"uri", "<e xmlns:a=\"uri\" />", "<e xmlns:a=\"uri\"" },
1586 { L
"prefix", L
"xmlns", L
"uri", L
"value", "<e prefix:xmlns=\"value\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"value\"" },
1587 { L
"prefix", L
"xmlns", L
"uri", NULL
, "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1588 { L
"prefix", L
"xmlns", L
"uri", L
"", "<e prefix:xmlns=\"\" xmlns:prefix=\"uri\" />", "<e prefix:xmlns=\"\"" },
1589 { L
"prefix", L
"xmlns", NULL
, L
"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1590 { L
"prefix", L
"xmlns", L
"", L
"uri", "<e xmlns=\"uri\" />", "<e xmlns=\"uri\"" },
1591 { L
"xml", L
"space", NULL
, L
"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1592 { L
"xml", L
"space", L
"", L
"preserve", "<e xml:space=\"preserve\" />", "<e xml:space=\"preserve\"" },
1593 { L
"xml", L
"space", NULL
, L
"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1594 { L
"xml", L
"space", L
"", L
"default", "<e xml:space=\"default\" />", "<e xml:space=\"default\"" },
1595 { L
"xml", L
"a", NULL
, L
"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1596 { L
"xml", L
"a", L
"", L
"value", "<e xml:a=\"value\" />", "<e xml:a=\"value\"" },
1598 /* Autogenerated prefix names. */
1599 { NULL
, L
"a", L
"defuri", NULL
, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1600 { NULL
, L
"a", L
"defuri", L
"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK
, 1, 1, 1 },
1601 { L
"", L
"a", L
"defuri", NULL
, "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1602 { NULL
, L
"a", L
"defuri", L
"", "<e p1:a=\"\" xmlns:p1=\"defuri\" />", "<e p1:a=\"\"", S_OK
, 1, 1, 1 },
1603 { L
"", L
"a", L
"defuri", L
"b", "<e p1:a=\"b\" xmlns:p1=\"defuri\" />", "<e p1:a=\"b\"", S_OK
, 1, 1, 1 },
1605 /* Failing cases. */
1606 { NULL
, NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1607 { L
"", L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 1, 1, 1 },
1608 { L
"", NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1609 { L
"", L
"", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1610 { NULL
, L
"", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1611 { L
"prefix", L
"a", L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", WR_E_XMLNSURIDECLARATION
, 1, 1, 1 },
1612 { L
"prefix", NULL
, L
"http://www.w3.org/2000/xmlns/", L
"defuri", "<e />", "<e", E_INVALIDARG
},
1613 { L
"prefix", NULL
, NULL
, L
"b", "<e />", "<e", E_INVALIDARG
},
1614 { L
"prefix", NULL
, L
"uri", NULL
, "<e />", "<e", E_INVALIDARG
},
1615 { L
"xml", NULL
, NULL
, L
"value", "<e />", "<e", E_INVALIDARG
},
1616 { L
"xmlns", L
"a", L
"defuri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
},
1617 { L
"xmlns", L
"a", L
"b", L
"uri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
},
1618 { NULL
, L
"xmlns", L
"uri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 0, 0, 1 },
1619 { L
"xmlns", NULL
, L
"uri", NULL
, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION
, 0, 0, 1 },
1620 { L
"pre:fix", L
"local", L
"uri", L
"b", "<e />", "<e", WC_E_NAMECHARACTER
},
1621 { L
"pre:fix", NULL
, L
"uri", L
"b", "<e />", "<e", E_INVALIDARG
},
1622 { L
"prefix", L
"lo:cal", L
"uri", L
"b", "<e />", "<e", WC_E_NAMECHARACTER
},
1623 { L
"xmlns", NULL
, NULL
, L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1624 { L
"xmlns", NULL
, L
"", L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1625 { L
"xmlns", L
"", NULL
, L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1626 { L
"xmlns", L
"", L
"", L
"uri", "<e />", "<e", WR_E_NSPREFIXDECLARED
},
1627 { L
"xml", L
"space", L
"", L
"value", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1628 { L
"xml", L
"space", NULL
, L
"value", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1629 { L
"xml", L
"a", L
"uri", L
"value", "<e />", "<e", WR_E_XMLPREFIXDECLARATION
},
1630 { L
"xml", L
"space", NULL
, L
"preServe", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1631 { L
"xml", L
"space", NULL
, L
"defAult", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1632 { L
"xml", L
"space", NULL
, NULL
, "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1633 { L
"xml", L
"space", NULL
, L
"", "<e />", "<e", WR_E_INVALIDXMLSPACE
},
1641 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1642 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1644 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1646 for (i
= 0; i
< ARRAY_SIZE(attribute_tests
); ++i
)
1648 winetest_push_context("Test %u", i
);
1650 stream
= writer_set_output(writer
);
1652 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1653 ok(hr
== S_OK
, "Failed to start document, hr %#lx.\n", hr
);
1655 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"e", NULL
);
1656 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1658 hr
= IXmlWriter_WriteAttributeString(writer
, attribute_tests
[i
].prefix
, attribute_tests
[i
].local
,
1659 attribute_tests
[i
].uri
, attribute_tests
[i
].value
);
1660 todo_wine_if(attribute_tests
[i
].todo_hr
)
1661 ok(hr
== attribute_tests
[i
].hr
, "Unexpected hr %#lx, expected %#lx.\n", hr
, attribute_tests
[i
].hr
);
1663 hr
= IXmlWriter_Flush(writer
);
1664 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1666 check_output(stream
, attribute_tests
[i
].output_partial
, attribute_tests
[i
].todo_partial
, __LINE__
);
1668 hr
= IXmlWriter_WriteEndDocument(writer
);
1669 ok(hr
== S_OK
, "Failed to end document, hr %#lx.\n", hr
);
1671 hr
= IXmlWriter_Flush(writer
);
1672 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1674 check_output(stream
, attribute_tests
[i
].output
, attribute_tests
[i
].todo
, __LINE__
);
1675 IStream_Release(stream
);
1677 winetest_pop_context();
1680 /* With namespaces */
1681 stream
= writer_set_output(writer
);
1683 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1684 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1686 hr
= IXmlWriter_WriteStartElement(writer
, L
"p", L
"a", L
"outeruri");
1687 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1689 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"local", L
"uri", L
"b");
1690 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1692 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"a", NULL
, L
"b");
1693 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1695 hr
= IXmlWriter_WriteAttributeString(writer
, L
"xmlns", L
"prefix", NULL
, L
"uri");
1696 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1698 hr
= IXmlWriter_WriteAttributeString(writer
, L
"p", L
"attr", NULL
, L
"value");
1699 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1701 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"local", NULL
, L
"b");
1703 ok(hr
== WR_E_DUPLICATEATTRIBUTE
, "Unexpected hr %#lx.\n", hr
);
1705 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1706 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1708 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"attr2", L
"outeruri", L
"value");
1709 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1711 hr
= IXmlWriter_WriteAttributeString(writer
, L
"pr", L
"attr3", L
"outeruri", L
"value");
1712 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
1714 hr
= IXmlWriter_WriteEndDocument(writer
);
1715 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1717 hr
= IXmlWriter_Flush(writer
);
1718 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1720 CHECK_OUTPUT_TODO(stream
,
1721 "<p:a prefix:local=\"b\" a=\"b\" xmlns:prefix=\"uri\" p:attr=\"value\" xmlns:p=\"outeruri\">"
1722 "<b p:attr2=\"value\" pr:attr3=\"value\" xmlns:pr=\"outeruri\" />"
1725 IStream_Release(stream
);
1727 /* Define prefix, write attribute with it. */
1728 stream
= writer_set_output(writer
);
1730 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1731 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1733 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"e", NULL
);
1734 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1736 hr
= IXmlWriter_WriteAttributeString(writer
, L
"xmlns", L
"prefix", NULL
, L
"uri");
1737 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1739 hr
= IXmlWriter_WriteAttributeString(writer
, L
"prefix", L
"attr", NULL
, L
"value");
1740 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1742 hr
= IXmlWriter_WriteEndDocument(writer
);
1743 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1745 hr
= IXmlWriter_Flush(writer
);
1746 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1748 CHECK_OUTPUT(stream
,
1749 "<e xmlns:prefix=\"uri\" prefix:attr=\"value\" />");
1751 IStream_Release(stream
);
1753 IXmlWriter_Release(writer
);
1756 static void test_WriteFullEndElement(void)
1762 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1763 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1765 /* standalone element */
1766 stream
= writer_set_output(writer
);
1768 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1769 writer_set_property(writer
, XmlWriterProperty_Indent
);
1771 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1772 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1774 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1775 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1777 hr
= IXmlWriter_WriteFullEndElement(writer
);
1778 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1780 hr
= IXmlWriter_WriteEndDocument(writer
);
1781 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1783 hr
= IXmlWriter_Flush(writer
);
1784 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1786 CHECK_OUTPUT(stream
,
1788 IStream_Release(stream
);
1790 /* nested elements */
1791 stream
= writer_set_output(writer
);
1793 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1794 writer_set_property(writer
, XmlWriterProperty_Indent
);
1796 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1797 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1799 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1800 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1802 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1803 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1805 hr
= IXmlWriter_WriteFullEndElement(writer
);
1806 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1808 hr
= IXmlWriter_WriteEndDocument(writer
);
1809 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1811 hr
= IXmlWriter_Flush(writer
);
1812 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1814 CHECK_OUTPUT(stream
,
1818 IStream_Release(stream
);
1820 /* Empty strings for prefix and uri. */
1821 stream
= writer_set_output(writer
);
1823 hr
= IXmlWriter_SetProperty(writer
, XmlWriterProperty_Indent
, FALSE
);
1824 ok(hr
== S_OK
, "Failed to set property, hr %#lx.\n", hr
);
1826 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"a", NULL
);
1827 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1828 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", L
"");
1829 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1830 hr
= IXmlWriter_WriteStartElement(writer
, L
"", L
"c", L
"");
1831 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1832 hr
= IXmlWriter_WriteFullEndElement(writer
);
1833 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1834 hr
= IXmlWriter_WriteFullEndElement(writer
);
1835 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1836 hr
= IXmlWriter_WriteFullEndElement(writer
);
1837 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1839 hr
= IXmlWriter_Flush(writer
);
1840 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1841 CHECK_OUTPUT(stream
, "<a><b><c></c></b></a>");
1842 IStream_Release(stream
);
1844 IXmlWriter_Release(writer
);
1847 static void test_WriteCharEntity(void)
1853 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1854 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1856 /* without indentation */
1857 stream
= writer_set_output(writer
);
1859 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1861 hr
= IXmlWriter_WriteStartDocument(writer
, XmlStandalone_Omit
);
1862 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1864 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1865 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1867 hr
= IXmlWriter_WriteCharEntity(writer
, 0x100);
1868 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1870 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1871 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1873 hr
= IXmlWriter_WriteEndDocument(writer
);
1874 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1876 hr
= IXmlWriter_Flush(writer
);
1877 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1879 CHECK_OUTPUT(stream
,
1880 "<a>Ā<a /></a>");
1882 IXmlWriter_Release(writer
);
1883 IStream_Release(stream
);
1886 static void test_WriteString(void)
1892 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void**)&writer
, NULL
);
1893 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1895 writer_set_property(writer
, XmlWriterProperty_OmitXmlDeclaration
);
1897 hr
= IXmlWriter_WriteString(writer
, L
"a");
1898 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1900 hr
= IXmlWriter_WriteString(writer
, NULL
);
1901 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1903 hr
= IXmlWriter_WriteString(writer
, L
"");
1904 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
1906 stream
= writer_set_output(writer
);
1908 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1909 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1911 hr
= IXmlWriter_WriteString(writer
, NULL
);
1912 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1914 hr
= IXmlWriter_WriteString(writer
, L
"");
1915 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1917 hr
= IXmlWriter_WriteString(writer
, L
"a");
1918 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1920 /* WriteString automatically escapes markup characters */
1921 hr
= IXmlWriter_WriteString(writer
, L
"<&\">=");
1922 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1924 hr
= IXmlWriter_Flush(writer
);
1925 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1927 CHECK_OUTPUT(stream
,
1928 "<b>a<&\">=");
1929 IStream_Release(stream
);
1931 stream
= writer_set_output(writer
);
1933 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1934 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1936 hr
= IXmlWriter_WriteString(writer
, NULL
);
1937 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1939 hr
= IXmlWriter_Flush(writer
);
1940 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1942 CHECK_OUTPUT(stream
,
1945 hr
= IXmlWriter_WriteString(writer
, L
"");
1946 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1948 hr
= IXmlWriter_Flush(writer
);
1949 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1951 CHECK_OUTPUT(stream
,
1954 IStream_Release(stream
);
1955 IXmlWriter_Release(writer
);
1957 /* With indentation */
1958 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
1959 ok(hr
== S_OK
, "Failed to create a writer, hr %#lx.\n", hr
);
1961 stream
= writer_set_output(writer
);
1963 writer_set_property(writer
, XmlWriterProperty_Indent
);
1965 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
1966 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1968 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
1969 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
1971 hr
= IXmlWriter_WriteString(writer
, L
"text");
1972 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
1974 hr
= IXmlWriter_Flush(writer
);
1975 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1977 CHECK_OUTPUT(stream
,
1981 hr
= IXmlWriter_WriteFullEndElement(writer
);
1982 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
1984 hr
= IXmlWriter_Flush(writer
);
1985 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1987 CHECK_OUTPUT(stream
,
1991 hr
= IXmlWriter_WriteFullEndElement(writer
);
1992 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
1994 hr
= IXmlWriter_Flush(writer
);
1995 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1997 CHECK_OUTPUT(stream
,
2002 IStream_Release(stream
);
2004 stream
= writer_set_output(writer
);
2006 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"a", NULL
);
2007 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
2009 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"b", NULL
);
2010 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
2012 hr
= IXmlWriter_WriteEndElement(writer
);
2013 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2015 hr
= IXmlWriter_Flush(writer
);
2016 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2018 CHECK_OUTPUT(stream
,
2022 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"c", NULL
);
2023 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
2025 hr
= IXmlWriter_WriteAttributeString(writer
, NULL
, L
"attr", NULL
, L
"value");
2026 ok(hr
== S_OK
, "Failed to write attribute string, hr %#lx.\n", hr
);
2028 hr
= IXmlWriter_Flush(writer
);
2029 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2031 CHECK_OUTPUT(stream
,
2034 " <c attr=\"value\"");
2036 hr
= IXmlWriter_WriteString(writer
, L
"text");
2037 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
2039 hr
= IXmlWriter_Flush(writer
);
2040 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2042 CHECK_OUTPUT(stream
,
2045 " <c attr=\"value\">text");
2047 hr
= IXmlWriter_WriteEndElement(writer
);
2048 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2050 hr
= IXmlWriter_Flush(writer
);
2051 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2053 CHECK_OUTPUT(stream
,
2056 " <c attr=\"value\">text</c>");
2058 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"d", NULL
);
2059 ok(hr
== S_OK
, "Failed to start element, hr %#lx.\n", hr
);
2061 hr
= IXmlWriter_WriteString(writer
, L
"");
2062 ok(hr
== S_OK
, "Failed to write a string, hr %#lx.\n", hr
);
2064 hr
= IXmlWriter_WriteEndElement(writer
);
2065 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2067 hr
= IXmlWriter_Flush(writer
);
2068 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2070 CHECK_OUTPUT(stream
,
2073 " <c attr=\"value\">text</c>\r\n"
2076 hr
= IXmlWriter_WriteEndElement(writer
);
2077 ok(hr
== S_OK
, "Failed to end element, hr %#lx.\n", hr
);
2079 hr
= IXmlWriter_Flush(writer
);
2080 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2082 CHECK_OUTPUT(stream
,
2085 " <c attr=\"value\">text</c>\r\n"
2089 IXmlWriter_Release(writer
);
2090 IStream_Release(stream
);
2093 static void test_WriteDocType(void)
2100 const WCHAR
*subset
;
2105 { L
"a", L
"", NULL
, NULL
, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2106 { L
"a", NULL
, NULL
, NULL
, "<!DOCTYPE a>" },
2107 { L
"a", NULL
, L
"", NULL
, "<!DOCTYPE a SYSTEM \"\">" },
2108 { L
"a", L
"", L
"", NULL
, "<!DOCTYPE a PUBLIC \"\" \"\">" },
2109 { L
"a", L
"pubid", L
"", NULL
, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2110 { L
"a", L
"pubid", NULL
, NULL
, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" },
2111 { L
"a", L
"", L
"sysid", NULL
, "<!DOCTYPE a PUBLIC \"\" \"sysid\">" },
2112 { L
"a", NULL
, NULL
, L
"", "<!DOCTYPE a []>" },
2113 { L
"a", NULL
, NULL
, L
"subset", "<!DOCTYPE a [subset]>" },
2114 { L
"a", L
"", NULL
, L
"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2115 { L
"a", NULL
, L
"", L
"subset", "<!DOCTYPE a SYSTEM \"\" [subset]>" },
2116 { L
"a", L
"", L
"", L
"subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" },
2117 { L
"a", L
"pubid", NULL
, L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2118 { L
"a", L
"pubid", L
"", L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" },
2119 { L
"a", NULL
, L
"sysid", L
"subset", "<!DOCTYPE a SYSTEM \"sysid\" [subset]>" },
2120 { L
"a", L
"", L
"sysid", L
"subset", "<!DOCTYPE a PUBLIC \"\" \"sysid\" [subset]>" },
2121 { L
"a", L
"pubid", L
"sysid", L
"subset", "<!DOCTYPE a PUBLIC \"pubid\" \"sysid\" [subset]>" },
2123 static const WCHAR pubidW
[] = {'p',0x100,'i','d',0};
2129 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2130 ok(hr
== S_OK
, "Failed to create writer instance, hr %#lx.\n", hr
);
2132 stream
= writer_set_output(writer
);
2134 hr
= IXmlWriter_WriteDocType(writer
, NULL
, NULL
, NULL
, NULL
);
2135 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2137 hr
= IXmlWriter_WriteDocType(writer
, L
"", NULL
, NULL
, NULL
);
2138 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2140 /* Name validation. */
2141 hr
= IXmlWriter_WriteDocType(writer
, L
"-a", NULL
, NULL
, NULL
);
2142 ok(hr
== WC_E_NAMECHARACTER
, "Unexpected hr %#lx.\n", hr
);
2144 /* Pubid validation. */
2145 hr
= IXmlWriter_WriteDocType(writer
, L
"a", pubidW
, NULL
, NULL
);
2146 ok(hr
== WC_E_PUBLICID
, "Unexpected hr %#lx.\n", hr
);
2148 /* Invalid multi-character string */
2149 hr
= IXmlWriter_WriteDocType(writer
, L
":ax>m", NULL
, NULL
, NULL
);
2150 ok(hr
== WC_E_NAMECHARACTER
, "Unexpected hr %#lx.\n", hr
);
2152 /* Valid multi-character string */
2153 hr
= IXmlWriter_WriteDocType(writer
, L
"root", NULL
, NULL
, NULL
);
2154 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2156 IStream_Release(stream
);
2158 for (i
= 0; i
< ARRAY_SIZE(doctype_tests
); i
++)
2160 stream
= writer_set_output(writer
);
2162 hr
= IXmlWriter_WriteDocType(writer
, doctype_tests
[i
].name
, doctype_tests
[i
].pubid
, doctype_tests
[i
].sysid
,
2163 doctype_tests
[i
].subset
);
2164 ok(hr
== S_OK
, "%u: failed to write doctype, hr %#lx.\n", i
, hr
);
2166 hr
= IXmlWriter_Flush(writer
);
2167 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2169 CHECK_OUTPUT(stream
, doctype_tests
[i
].output
);
2171 hr
= IXmlWriter_WriteDocType(writer
, doctype_tests
[i
].name
, doctype_tests
[i
].pubid
, doctype_tests
[i
].sysid
,
2172 doctype_tests
[i
].subset
);
2173 ok(hr
== WR_E_INVALIDACTION
, "Unexpected hr %#lx.\n", hr
);
2175 IStream_Release(stream
);
2178 IXmlWriter_Release(writer
);
2181 static void test_WriteWhitespace(void)
2187 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2188 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2190 stream
= writer_set_output(writer
);
2192 hr
= IXmlWriter_WriteWhitespace(writer
, L
" ");
2193 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2194 hr
= IXmlWriter_WriteWhitespace(writer
, L
"ab");
2195 ok(hr
== WR_E_NONWHITESPACE
, "Unexpected hr %#lx.\n", hr
);
2196 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2197 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2198 hr
= IXmlWriter_WriteWhitespace(writer
, L
"\t");
2199 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2201 hr
= IXmlWriter_Flush(writer
);
2202 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2203 CHECK_OUTPUT(stream
, " <w>\t");
2204 IStream_Release(stream
);
2206 IXmlWriter_Release(writer
);
2209 static void test_WriteProcessingInstruction(void)
2215 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2216 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2218 stream
= writer_set_output(writer
);
2220 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2221 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2222 hr
= IXmlWriter_WriteProcessingInstruction(writer
, L
"pi", L
"content");
2223 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2225 hr
= IXmlWriter_Flush(writer
);
2226 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2227 CHECK_OUTPUT(stream
, "<w><?pi content?>");
2228 IStream_Release(stream
);
2230 IXmlWriter_Release(writer
);
2233 static void test_WriteAttributes(void)
2235 XmlNodeType node_type
;
2242 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2243 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2245 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2246 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2248 /* No attributes. */
2249 reader_set_input(reader
, "<a/>");
2250 stream
= writer_set_output(writer
);
2251 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2252 ok(hr
== E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
2253 hr
= IXmlReader_Read(reader
, NULL
);
2254 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2255 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2256 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2257 hr
= IXmlWriter_Flush(writer
);
2258 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2259 CHECK_OUTPUT(stream
, "");
2260 IStream_Release(stream
);
2262 /* Position on element with attributes. */
2263 reader_set_input(reader
, "<a attr1=\'b\' attr2=\'c\' attr3=\'d\' />");
2264 stream
= writer_set_output(writer
);
2265 hr
= IXmlReader_Read(reader
, NULL
);
2266 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2267 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2268 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2269 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2270 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2271 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2272 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2273 ok(node_type
== XmlNodeType_Element
, "Unexpected node type %d.\n", node_type
);
2274 hr
= IXmlWriter_Flush(writer
);
2275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2276 CHECK_OUTPUT(stream
, "<w attr1=\"b\" attr2=\"c\" attr3=\"d\"");
2277 IStream_Release(stream
);
2279 /* Position on second attribute. */
2280 hr
= IXmlReader_MoveToAttributeByName(reader
, L
"attr2", NULL
);
2281 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2282 stream
= writer_set_output(writer
);
2283 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2284 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2285 hr
= IXmlWriter_WriteAttributes(writer
, reader
, FALSE
);
2286 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2287 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2288 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2289 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type %d.\n", node_type
);
2290 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2291 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2292 ok(!wcscmp(name
, L
"attr3"), "Unexpected node %s.\n", debugstr_w(name
));
2293 hr
= IXmlWriter_Flush(writer
);
2294 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2295 CHECK_OUTPUT(stream
, "<w attr2=\"c\" attr3=\"d\"");
2296 IStream_Release(stream
);
2298 IXmlWriter_Release(writer
);
2299 IXmlReader_Release(reader
);
2302 static void test_WriteNode(void)
2308 XmlNodeType node_type
;
2310 write_node_tests
[] =
2312 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment
},
2313 { "<r>text</r>", "<w>text", XmlNodeType_Text
},
2314 { "<r> </r>", "<w> ", XmlNodeType_Whitespace
},
2315 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA
},
2316 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction
},
2317 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1><e2 attr1=\"a\" /></e1>", XmlNodeType_Element
},
2318 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element
},
2319 { "<r></r>", "<w></w>", XmlNodeType_EndElement
},
2321 XmlNodeType node_type
;
2329 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2330 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2332 hr
= IXmlWriter_WriteNode(writer
, NULL
, FALSE
);
2333 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2335 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2336 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2338 for (i
= 0; i
< ARRAY_SIZE(write_node_tests
); ++i
)
2340 winetest_push_context("Test %s", debugstr_a(write_node_tests
[i
].input
));
2342 stream
= writer_set_output(writer
);
2343 reader_set_input(reader
, write_node_tests
[i
].input
);
2345 /* Skip top level element. */
2346 hr
= IXmlReader_Read(reader
, &node_type
);
2347 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2349 hr
= IXmlReader_Read(reader
, &node_type
);
2350 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2351 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type %d.\n", node_type
);
2353 /* Always write a root node to give a valid context for following nodes. */
2354 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2355 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2356 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2357 ok(SUCCEEDED(hr
), "Failed to write a node, hr %#lx.\n", hr
);
2361 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2362 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2363 ok(node_type
== XmlNodeType_EndElement
, "Unexpected node type on return %d.\n", node_type
);
2364 hr
= IXmlReader_GetLocalName(reader
, &name
, NULL
);
2365 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2366 ok(!wcscmp(name
, L
"r"), "Unexpected node name %s.\n", debugstr_w(name
));
2369 hr
= IXmlWriter_Flush(writer
);
2370 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2372 CHECK_OUTPUT(stream
, write_node_tests
[i
].output
);
2374 IStream_Release(stream
);
2376 winetest_pop_context();
2379 /* Current node is an attribute. */
2380 reader_set_input(reader
, "<a attr=\'b\' ></a>");
2381 hr
= IXmlReader_Read(reader
, &node_type
);
2382 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2383 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2384 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2385 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2387 stream
= writer_set_output(writer
);
2388 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2389 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2390 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2391 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2392 ok(node_type
== XmlNodeType_EndElement
, "Unexpected node type on return %d.\n", node_type
);
2393 hr
= IXmlWriter_Flush(writer
);
2394 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2395 CHECK_OUTPUT(stream
, "");
2396 IStream_Release(stream
);
2398 /* Xml declaration node. */
2399 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a/>");
2400 hr
= IXmlReader_Read(reader
, &node_type
);
2401 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2402 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2404 stream
= writer_set_output(writer
);
2405 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2406 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2407 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2408 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2409 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2410 hr
= IXmlWriter_Flush(writer
);
2411 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2412 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2413 IStream_Release(stream
);
2415 /* With standalone attribute. */
2416 reader_set_input(reader
, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2417 hr
= IXmlReader_Read(reader
, &node_type
);
2418 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2419 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2421 stream
= writer_set_output(writer
);
2422 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2423 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2424 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2425 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2426 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2427 hr
= IXmlWriter_Flush(writer
);
2428 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2429 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2430 IStream_Release(stream
);
2432 /* Initial state. */
2433 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a><b/></a>");
2434 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2435 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2436 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2437 stream
= writer_set_output(writer
);
2438 hr
= IXmlWriter_WriteNode(writer
, reader
, FALSE
);
2439 ok(hr
== S_FALSE
, "Failed to write a node, hr %#lx.\n", hr
);
2440 node_type
= XmlNodeType_Element
;
2441 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2443 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
2444 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2445 hr
= IXmlWriter_Flush(writer
);
2446 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2447 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><a><b /></a>");
2448 IStream_Release(stream
);
2450 IXmlReader_Release(reader
);
2451 IXmlWriter_Release(writer
);
2454 static void test_WriteNodeShallow(void)
2460 XmlNodeType node_type
;
2462 write_node_tests
[] =
2464 { "<r><!-- comment --></r>", "<w><!-- comment -->", XmlNodeType_Comment
},
2465 { "<r>text</r>", "<w>text", XmlNodeType_Text
},
2466 { "<r> </r>", "<w> ", XmlNodeType_Whitespace
},
2467 { "<r><![CDATA[ cdata ]]></r>", "<w><![CDATA[ cdata ]]>", XmlNodeType_CDATA
},
2468 { "<r><?pi pidata ?></r>", "<w><?pi pidata ?>", XmlNodeType_ProcessingInstruction
},
2469 { "<r><e1><e2 attr1=\'a\'/></e1></r>", "<w><e1", XmlNodeType_Element
},
2470 { "<r><e1/></r>", "<w><e1 />", XmlNodeType_Element
},
2471 { "<r><e1 attr1=\'a\'/></r>", "<w><e1 attr1=\"a\" />", XmlNodeType_Element
},
2472 { "<r><e1 attr1=\'a\'></e1></r>", "<w><e1 attr1=\"a\"", XmlNodeType_Element
},
2473 { "<r></r>", "<w></w>", XmlNodeType_EndElement
},
2475 XmlNodeType node_type
;
2482 hr
= CreateXmlWriter(&IID_IXmlWriter
, (void **)&writer
, NULL
);
2483 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2485 hr
= IXmlWriter_WriteNodeShallow(writer
, NULL
, FALSE
);
2486 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2488 hr
= CreateXmlReader(&IID_IXmlReader
, (void **)&reader
, NULL
);
2489 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2491 for (i
= 0; i
< ARRAY_SIZE(write_node_tests
); ++i
)
2493 winetest_push_context("Test %s", debugstr_a(write_node_tests
[i
].input
));
2495 stream
= writer_set_output(writer
);
2496 reader_set_input(reader
, write_node_tests
[i
].input
);
2498 /* Skip top level element. */
2499 hr
= IXmlReader_Read(reader
, &node_type
);
2500 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2502 hr
= IXmlReader_Read(reader
, &node_type
);
2503 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2504 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type %d.\n", node_type
);
2506 /* Always write a root node to give a valid context for following nodes. */
2507 hr
= IXmlWriter_WriteStartElement(writer
, NULL
, L
"w", NULL
);
2508 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2509 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2510 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2512 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2513 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2514 ok(node_type
== write_node_tests
[i
].node_type
, "Unexpected node type on return %d.\n", node_type
);
2516 hr
= IXmlWriter_Flush(writer
);
2517 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2519 CHECK_OUTPUT(stream
, write_node_tests
[i
].output
);
2521 IStream_Release(stream
);
2523 winetest_pop_context();
2526 /* Current node is an attribute. */
2527 reader_set_input(reader
, "<a attr=\'b\' ></a>");
2528 hr
= IXmlReader_Read(reader
, &node_type
);
2529 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2530 ok(node_type
== XmlNodeType_Element
, "Unexpected node type on return %d.\n", node_type
);
2531 hr
= IXmlReader_MoveToFirstAttribute(reader
);
2532 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2534 stream
= writer_set_output(writer
);
2535 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2536 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2537 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2538 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2539 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2540 hr
= IXmlWriter_Flush(writer
);
2541 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2542 CHECK_OUTPUT(stream
, "");
2543 IStream_Release(stream
);
2545 /* Xml declaration node. */
2546 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a/>");
2547 hr
= IXmlReader_Read(reader
, &node_type
);
2548 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2549 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2551 stream
= writer_set_output(writer
);
2552 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2553 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2554 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2555 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2556 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2557 hr
= IXmlWriter_Flush(writer
);
2558 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2559 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
2560 IStream_Release(stream
);
2562 /* With standalone attribute. */
2563 reader_set_input(reader
, "<?xml version=\"1.0\" standalone=\'yes\'?><a/>");
2564 hr
= IXmlReader_Read(reader
, &node_type
);
2565 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2566 ok(node_type
== XmlNodeType_XmlDeclaration
, "Unexpected node type on return %d.\n", node_type
);
2568 stream
= writer_set_output(writer
);
2569 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2570 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2571 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2572 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2573 ok(node_type
== XmlNodeType_Attribute
, "Unexpected node type on return %d.\n", node_type
);
2574 hr
= IXmlWriter_Flush(writer
);
2575 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2576 CHECK_OUTPUT(stream
, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
2577 IStream_Release(stream
);
2579 /* Initial state. */
2580 reader_set_input(reader
, "<?xml version=\"1.0\" ?><a><b/></a>");
2581 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2582 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2583 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2584 stream
= writer_set_output(writer
);
2585 hr
= IXmlWriter_WriteNodeShallow(writer
, reader
, FALSE
);
2586 ok(hr
== S_OK
, "Failed to write a node, hr %#lx.\n", hr
);
2587 node_type
= XmlNodeType_Element
;
2588 hr
= IXmlReader_GetNodeType(reader
, &node_type
);
2589 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2590 ok(node_type
== XmlNodeType_None
, "Unexpected node type on return %d.\n", node_type
);
2591 hr
= IXmlWriter_Flush(writer
);
2592 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
2593 CHECK_OUTPUT(stream
, "");
2594 IStream_Release(stream
);
2596 IXmlReader_Release(reader
);
2597 IXmlWriter_Release(writer
);
2602 test_writer_create();
2603 test_writer_state();
2604 test_writeroutput();
2605 test_writestartdocument();
2606 test_WriteStartElement();
2607 test_WriteElementString();
2608 test_WriteEndElement();
2610 test_omitxmldeclaration();
2612 test_writeenddocument();
2613 test_WriteComment();
2617 test_WriteAttributeString();
2618 test_WriteFullEndElement();
2619 test_WriteCharEntity();
2621 test_WriteDocType();
2622 test_WriteWhitespace();
2623 test_WriteProcessingInstruction();
2624 test_WriteAttributes();
2626 test_WriteNodeShallow();