https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4d74a058bd0862bd4b731f...
commit 4d74a058bd0862bd4b731f536ae069a7bd12c9a7 Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Mon Dec 23 00:56:47 2019 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Mon Dec 23 00:56:47 2019 +0100
[XMLLITE_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/xmllite/writer.c | 839 ++++++++++++++++++++++++---- 1 file changed, 734 insertions(+), 105 deletions(-)
diff --git a/modules/rostests/winetests/xmllite/writer.c b/modules/rostests/winetests/xmllite/writer.c index 8a15f384cb2..4e91419829d 100644 --- a/modules/rostests/winetests/xmllite/writer.c +++ b/modules/rostests/winetests/xmllite/writer.c @@ -31,6 +31,8 @@ #include "winbase.h" #include "ole2.h" #include "xmllite.h" + +#include "wine/heap.h" #include "wine/test.h"
#include "initguid.h" @@ -52,16 +54,18 @@ static void check_output_raw(IStream *stream, const void *expected, SIZE_T size, SIZE_T content_size; HGLOBAL hglobal; HRESULT hr; - char *ptr; + WCHAR *ptr;
hr = GetHGlobalFromStream(stream, &hglobal); ok_(__FILE__, line)(hr == S_OK, "Failed to get the stream handle, hr %#x.\n", hr);
content_size = GlobalSize(hglobal); - ok_(__FILE__, line)(size <= content_size, "Unexpected test output size.\n"); + ok_(__FILE__, line)(size == content_size, "Unexpected test output size %ld.\n", content_size); ptr = GlobalLock(hglobal); if (size <= content_size) ok_(__FILE__, line)(!memcmp(expected, ptr, size), "Unexpected output content.\n"); + if (size != content_size && *ptr == 0xfeff) + ok_(__FILE__, line)(0, "Content: %s.\n", wine_dbgstr_wn(ptr, content_size / sizeof(WCHAR)));
GlobalUnlock(hglobal); } @@ -94,6 +98,19 @@ static void check_output(IStream *stream, const char *expected, BOOL todo, int l #define CHECK_OUTPUT_TODO(stream, expected) check_output(stream, expected, TRUE, __LINE__) #define CHECK_OUTPUT_RAW(stream, expected, size) check_output_raw(stream, expected, size, __LINE__)
+static WCHAR *strdupAtoW(const char *str) +{ + WCHAR *ret = NULL; + DWORD len; + + if (!str) return ret; + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = heap_alloc(len * sizeof(WCHAR)); + if (ret) + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + return ret; +} + static void writer_set_property(IXmlWriter *writer, XmlWriterProperty property) { HRESULT hr; @@ -125,7 +142,8 @@ static void check_writer_state(IXmlWriter *writer, HRESULT exp_hr) hr = IXmlWriter_WriteComment(writer, aW); ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
- /* FIXME: add WriteDocType */ + hr = IXmlWriter_WriteDocType(writer, aW, NULL, NULL, NULL); + ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr);
hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, aW); ok(hr == exp_hr, "got 0x%08x, expected 0x%08x\n", hr, exp_hr); @@ -343,7 +361,8 @@ static void test_invalid_output_encoding(IXmlWriter *writer, IUnknown *output) hr = IXmlWriter_WriteComment(writer, aW); ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
- /* TODO: WriteDocType */ + hr = IXmlWriter_WriteDocType(writer, aW, NULL, NULL, NULL); + ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr);
hr = IXmlWriter_WriteElementString(writer, NULL, aW, NULL, NULL); ok(hr == MX_E_ENCODING, "Unexpected hr %#x.\n", hr); @@ -471,6 +490,7 @@ todo_wine CHECK_OUTPUT_RAW(stream, utf16_outputW, sizeof(utf16_outputW));
IStream_Release(stream); + IUnknown_Release(output);
/* Create output with meaningless code page value. */ hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); @@ -706,11 +726,14 @@ static void test_omitxmldeclaration(void)
static void test_bom(void) { + static const WCHAR piW[] = {0xfeff,'<','?','x','m','l',' ','v','e','r','s','i','o','n','=','"','1','.','0','"','?','>'}; + static const WCHAR aopenW[] = {0xfeff,'<','a'}; + static const WCHAR afullW[] = {0xfeff,'<','a',' ','/','>'}; static const WCHAR versionW[] = {'v','e','r','s','i','o','n','=','"','1','.','0','"',0}; static const WCHAR utf16W[] = {'u','t','f','-','1','6',0}; static const WCHAR xmlW[] = {'x','m','l',0}; + static const WCHAR bomW[] = {0xfeff}; IXmlWriterOutput *output; - unsigned char *ptr; IXmlWriter *writer; IStream *stream; HGLOBAL hglobal; @@ -737,12 +760,7 @@ static void test_bom(void) hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = GetHGlobalFromStream(stream, &hglobal); - ok(hr == S_OK, "got 0x%08x\n", hr); - - ptr = GlobalLock(hglobal); - ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]); - GlobalUnlock(hglobal); + CHECK_OUTPUT_RAW(stream, bomW, sizeof(bomW));
IStream_Release(stream); IUnknown_Release(output); @@ -763,12 +781,7 @@ static void test_bom(void) hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = GetHGlobalFromStream(stream, &hglobal); - ok(hr == S_OK, "got 0x%08x\n", hr); - - ptr = GlobalLock(hglobal); - ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]); - GlobalUnlock(hglobal); + CHECK_OUTPUT_RAW(stream, piW, sizeof(piW));
IUnknown_Release(output); IStream_Release(stream); @@ -789,12 +802,7 @@ static void test_bom(void) hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = GetHGlobalFromStream(stream, &hglobal); - ok(hr == S_OK, "got 0x%08x\n", hr); - - ptr = GlobalLock(hglobal); - ok(ptr[0] == 0xff && ptr[1] == 0xfe, "got %x,%x\n", ptr[0], ptr[1]); - GlobalUnlock(hglobal); + CHECK_OUTPUT_RAW(stream, aopenW, sizeof(aopenW));
IUnknown_Release(output); IStream_Release(stream); @@ -820,10 +828,7 @@ static void test_bom(void) hr = GetHGlobalFromStream(stream, &hglobal); ok(hr == S_OK, "got 0x%08x\n", hr);
- ptr = GlobalLock(hglobal); - ok(ptr[0] == 0xff && ptr[1] == 0xfe && ptr[2] == '<', "Unexpected output: %#x,%#x,%#x\n", - ptr[0], ptr[1], ptr[2]); - GlobalUnlock(hglobal); + CHECK_OUTPUT_RAW(stream, afullW, sizeof(afullW));
IUnknown_Release(output); IStream_Release(stream); @@ -831,33 +836,105 @@ static void test_bom(void) IXmlWriter_Release(writer); }
-static void test_writestartelement(void) +static HRESULT write_start_element(IXmlWriter *writer, const char *prefix, const char *local, + const char *uri) +{ + WCHAR *prefixW, *localW, *uriW; + HRESULT hr; + + prefixW = strdupAtoW(prefix); + localW = strdupAtoW(local); + uriW = strdupAtoW(uri); + + hr = IXmlWriter_WriteStartElement(writer, prefixW, localW, uriW); + + heap_free(prefixW); + heap_free(localW); + heap_free(uriW); + + return hr; +} + +static HRESULT write_element_string(IXmlWriter *writer, const char *prefix, const char *local, + const char *uri, const char *value) { - static const WCHAR valueW[] = {'v','a','l','u','e',0}; + WCHAR *prefixW, *localW, *uriW, *valueW; + HRESULT hr; + + prefixW = strdupAtoW(prefix); + localW = strdupAtoW(local); + uriW = strdupAtoW(uri); + valueW = strdupAtoW(value); + + hr = IXmlWriter_WriteElementString(writer, prefixW, localW, uriW, valueW); + + heap_free(prefixW); + heap_free(localW); + heap_free(uriW); + heap_free(valueW); + + return hr; +} + +static HRESULT write_string(IXmlWriter *writer, const char *str) +{ + WCHAR *strW; + HRESULT hr; + + strW = strdupAtoW(str); + + hr = IXmlWriter_WriteString(writer, strW); + + heap_free(strW); + + return hr; +} + +static void test_WriteStartElement(void) +{ + static const struct + { + const char *prefix; + const char *local; + const char *uri; + const char *output; + const char *output_partial; + HRESULT hr; + int todo; + int todo_partial; + } + start_element_tests[] = + { + { "prefix", "local", "uri", "<prefix:local xmlns:prefix="uri" />", "<prefix:local" }, + { NULL, "local", "uri", "<local xmlns="uri" />", "<local" }, + { "", "local", "uri", "<local xmlns="uri" />", "<local" }, + { "", "local", "uri", "<local xmlns="uri" />", "<local" }, + + { "prefix", NULL, NULL, NULL, NULL, E_INVALIDARG }, + { NULL, NULL, "uri", NULL, NULL, E_INVALIDARG }, + { NULL, NULL, NULL, NULL, NULL, E_INVALIDARG }, + { NULL, "prefix:local", "uri", NULL, NULL, WC_E_NAMECHARACTER }, + { "pre:fix", "local", "uri", NULL, NULL, WC_E_NAMECHARACTER }, + { NULL, ":local", "uri", NULL, NULL, WC_E_NAMECHARACTER }, + { ":", "local", "uri", NULL, NULL, WC_E_NAMECHARACTER }, + { NULL, "local", "http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSPREFIXDECLARATION }, + { "prefix", "local", "http://www.w3.org/2000/xmlns/", NULL, NULL, WR_E_XMLNSURIDECLARATION }, + }; static const WCHAR aW[] = {'a',0}; - static const WCHAR bW[] = {'b',0}; IXmlWriter *writer; IStream *stream; + unsigned int i; HRESULT hr;
hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, NULL, "a", NULL); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
stream = writer_set_output(writer);
- hr = IXmlWriter_WriteStartElement(writer, aW, NULL, NULL); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, NULL); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteStartElement(writer, NULL, NULL, aW); - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, NULL, "a", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Yes); @@ -884,34 +961,222 @@ static void test_writestartelement(void) hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, valueW); + hr = write_element_string(writer, NULL, "b", NULL, "value"); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
stream = writer_set_output(writer);
- hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, "prefix", "a", "uri"); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_element_string(writer, NULL, "b", NULL, "value"); + ok(hr == S_OK, "Failed to write element string, hr %#x.\n", hr); + + hr = write_element_string(writer, NULL, "c", NULL, NULL); + ok(hr == S_OK, "Failed to write element string, hr %#x.\n", hr); + + hr = write_start_element(writer, NULL, "d", "uri"); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_start_element(writer, "", "e", "uri"); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_start_element(writer, "prefix2", "f", "uri"); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "got 0x%08x\n", hr); + + CHECK_OUTPUT(stream, + "<prefix:a xmlns:prefix="uri">" + "<b>value</b>" + "<c />" + "prefix:d" + "<e xmlns="uri">" + "<prefix2:f"); + + IStream_Release(stream); + + /* WriteStartElement */ + for (i = 0; i < ARRAY_SIZE(start_element_tests); ++i) + { + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr); + + hr = write_start_element(writer, start_element_tests[i].prefix, start_element_tests[i].local, + start_element_tests[i].uri); + ok(hr == start_element_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr); + + if (SUCCEEDED(start_element_tests[i].hr)) + { + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, start_element_tests[i].output_partial, start_element_tests[i].todo_partial, __LINE__); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, start_element_tests[i].output, start_element_tests[i].todo, __LINE__); + } + + IStream_Release(stream); + } + + IXmlWriter_Release(writer); +} + +static void test_WriteElementString(void) +{ + static const struct + { + const char *prefix; + const char *local; + const char *uri; + const char *value; + const char *output; + HRESULT hr; + int todo; + } + element_string_tests[] = + { + { "prefix", "local", "uri", "value", "<prefix:local xmlns:prefix="uri">value</prefix:local>" }, + { NULL, "local", "uri", "value", "<local xmlns="uri">value</local>" }, + { "", "local", "uri", "value", "<local xmlns="uri">value</local>" }, + { "prefix", "local", "uri", NULL, "<prefix:local xmlns:prefix="uri" />" }, + { NULL, "local", "uri", NULL, "<local xmlns="uri" />" }, + { "", "local", "uri", NULL, "<local xmlns="uri" />" }, + { NULL, "local", NULL, NULL, "<local />" }, + { "prefix", "local", "uri", "", "<prefix:local xmlns:prefix="uri"></prefix:local>" }, + { NULL, "local", "uri", "", "<local xmlns="uri"></local>" }, + { "", "local", "uri", "", "<local xmlns="uri"></local>" }, + { NULL, "local", NULL, "", "<local></local>" }, + { "", "local", "http://www.w3.org/2000/xmlns/", NULL, "<local xmlns="http://www.w3.org/2000/xmlns/%5C" />" }, + + { "prefix", NULL, NULL, "value", NULL, E_INVALIDARG }, + { NULL, NULL, "uri", "value", NULL, E_INVALIDARG }, + { NULL, NULL, NULL, "value", NULL, E_INVALIDARG }, + { NULL, "prefix:local", "uri", "value", NULL, WC_E_NAMECHARACTER }, + { NULL, ":local", "uri", "value", NULL, WC_E_NAMECHARACTER }, + { ":", "local", "uri", "value", NULL, WC_E_NAMECHARACTER }, + { "prefix", "local", NULL, "value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI }, + { "prefix", "local", "", "value", NULL, WR_E_NSPREFIXWITHEMPTYNSURI }, + { NULL, "local", "http://www.w3.org/2000/xmlns/", "value", NULL, WR_E_XMLNSPREFIXDECLARATION }, + { "prefix", "local", "http://www.w3.org/2000/xmlns/", "value", NULL, WR_E_XMLNSURIDECLARATION }, + }; + IXmlWriter *writer; + IStream *stream; + unsigned int i; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); + ok(hr == S_OK, "Expected S_OK, got %08x\n", hr); + + hr = write_element_string(writer, NULL, "b", NULL, "value"); + ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr); + + stream = writer_set_output(writer); + + hr = write_start_element(writer, NULL, "a", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, valueW); + hr = write_element_string(writer, NULL, "b", NULL, "value"); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteElementString(writer, NULL, bW, NULL, NULL); + hr = write_element_string(writer, NULL, "b", NULL, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = write_element_string(writer, "prefix", "b", "uri", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = write_start_element(writer, "prefix", "c", "uri"); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_element_string(writer, "prefix", "d", NULL, NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, "prefix2", "d", "uri", NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, NULL, "e", "uri", NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, "prefix", "f", "uri2", NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, NULL, "g", "uri3", NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, "prefix", "h", NULL, NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, "prefix_i", "i", NULL, NULL); + ok(hr == WR_E_NSPREFIXWITHEMPTYNSURI, "Failed to write element, hr %#x.\n", hr); + + hr = write_element_string(writer, "", "j", "uri", NULL); + ok(hr == S_OK, "Failed to write element, hr %#x.\n", hr); + hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
CHECK_OUTPUT(stream, - "<a><b>value</b><b />"); + "<a><b>value</b><b />" + "<prefix:b xmlns:prefix="uri" />" + "<prefix:c xmlns:prefix="uri">" + "<prefix:d />" + "<prefix2:d xmlns:prefix2="uri" />" + "<prefix:e />" + "<prefix:f xmlns:prefix="uri2" />" + "<g xmlns="uri3" />" + "<prefix:h />" + "<j xmlns="uri" />");
IStream_Release(stream); + + for (i = 0; i < ARRAY_SIZE(element_string_tests); ++i) + { + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr); + + hr = write_element_string(writer, element_string_tests[i].prefix, element_string_tests[i].local, + element_string_tests[i].uri, element_string_tests[i].value); + ok(hr == element_string_tests[i].hr, "%u: unexpected hr %#x.\n", i, hr); + + if (SUCCEEDED(element_string_tests[i].hr)) + { + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, element_string_tests[i].output, element_string_tests[i].todo, __LINE__); + } + + IStream_Release(stream); + } + IXmlWriter_Release(writer); }
-static void test_writeendelement(void) +static void test_WriteEndElement(void) { - static const WCHAR aW[] = {'a',0}; - static const WCHAR bW[] = {'b',0}; IXmlWriter *writer; IStream *stream; HRESULT hr; @@ -921,10 +1186,10 @@ static void test_writeendelement(void)
stream = writer_set_output(writer);
- hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, NULL, "a", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + hr = write_start_element(writer, NULL, "b", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_WriteEndElement(writer); @@ -1316,88 +1581,216 @@ static void test_indentation(void) IXmlWriter_Release(writer); }
+static HRESULT write_attribute_string(IXmlWriter *writer, const char *prefix, const char *local, + const char *uri, const char *value) +{ + WCHAR *prefixW, *localW, *uriW, *valueW; + HRESULT hr; + + prefixW = strdupAtoW(prefix); + localW = strdupAtoW(local); + uriW = strdupAtoW(uri); + valueW = strdupAtoW(value); + + hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, uriW, valueW); + + heap_free(prefixW); + heap_free(localW); + heap_free(uriW); + heap_free(valueW); + + return hr; +} + static void test_WriteAttributeString(void) { - static const WCHAR prefixW[] = {'p','r','e','f','i','x',0}; - static const WCHAR localW[] = {'l','o','c','a','l',0}; - static const WCHAR uriW[] = {'u','r','i',0}; - static const WCHAR uri2W[] = {'u','r','i','2',0}; - static const WCHAR xmlnsW[] = {'x','m','l','n','s',0}; - static const WCHAR aW[] = {'a',0}; - static const WCHAR bW[] = {'b',0}; + static const struct + { + const char *prefix; + const char *local; + const char *uri; + const char *value; + const char *output; + const char *output_partial; + HRESULT hr; + int todo; + int todo_partial; + int todo_hr; + } + attribute_tests[] = + { + { NULL, "a", NULL, "b", "<e a="b" />", "<e a="b"" }, + { "", "a", NULL, "b", "<e a="b" />", "<e a="b"" }, + { NULL, "a", "", "b", "<e a="b" />", "<e a="b"" }, + { "", "a", "", "b", "<e a="b" />", "<e a="b"" }, + { "prefix", "local", "uri", "b", "<e prefix:local="b" xmlns:prefix="uri" />", "<e prefix:local="b"" }, + { NULL, "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e xmlns:a="defuri" />", "<e xmlns:a="defuri"" }, + { "xmlns", "a", NULL, "uri", "<e xmlns:a="uri" />", "<e xmlns:a="uri"" }, + { "xmlns", "a", "", "uri", "<e xmlns:a="uri" />", "<e xmlns:a="uri"" }, + { "prefix", "xmlns", "uri", "value", "<e prefix:xmlns="value" xmlns:prefix="uri" />", "<e prefix:xmlns="value"" }, + { "prefix", "xmlns", "uri", NULL, "<e prefix:xmlns="" xmlns:prefix="uri" />", "<e prefix:xmlns=""" }, + { "prefix", "xmlns", "uri", "", "<e prefix:xmlns="" xmlns:prefix="uri" />", "<e prefix:xmlns=""" }, + { "prefix", "xmlns", NULL, "uri", "<e xmlns="uri" />", "<e xmlns="uri"" }, + { "prefix", "xmlns", "", "uri", "<e xmlns="uri" />", "<e xmlns="uri"" }, + { "xml", "space", NULL, "preserve", "<e xml:space="preserve" />", "<e xml:space="preserve"" }, + { "xml", "space", "", "preserve", "<e xml:space="preserve" />", "<e xml:space="preserve"" }, + { "xml", "space", NULL, "default", "<e xml:space="default" />", "<e xml:space="default"" }, + { "xml", "space", "", "default", "<e xml:space="default" />", "<e xml:space="default"" }, + { "xml", "a", NULL, "value", "<e xml:a="value" />", "<e xml:a="value"" }, + { "xml", "a", "", "value", "<e xml:a="value" />", "<e xml:a="value"" }, + + /* Autogenerated prefix names. */ + { NULL, "a", "defuri", NULL, "<e p1:a="" xmlns:p1="defuri" />", "<e p1:a=""", S_OK, 1, 1, 1 }, + { NULL, "a", "defuri", "b", "<e p1:a="b" xmlns:p1="defuri" />", "<e p1:a="b"", S_OK, 1, 1, 1 }, + { "", "a", "defuri", NULL, "<e p1:a="" xmlns:p1="defuri" />", "<e p1:a=""", S_OK, 1, 1, 1 }, + { NULL, "a", "defuri", "", "<e p1:a="" xmlns:p1="defuri" />", "<e p1:a=""", S_OK, 1, 1, 1 }, + { "", "a", "defuri", "b", "<e p1:a="b" xmlns:p1="defuri" />", "<e p1:a="b"", S_OK, 1, 1, 1 }, + + /* Failing cases. */ + { NULL, NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG }, + { "", "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 1, 1, 1 }, + { "", NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG }, + { "", "", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG, 1, 1, 1 }, + { NULL, "", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG, 1, 1, 1 }, + { "prefix", "a", "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", WR_E_XMLNSURIDECLARATION, 1, 1, 1 }, + { "prefix", NULL, "http://www.w3.org/2000/xmlns/", "defuri", "<e />", "<e", E_INVALIDARG }, + { "prefix", NULL, NULL, "b", "<e />", "<e", E_INVALIDARG }, + { "prefix", NULL, "uri", NULL, "<e />", "<e", E_INVALIDARG }, + { "xml", NULL, NULL, "value", "<e />", "<e", E_INVALIDARG }, + { "xmlns", "a", "defuri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION }, + { "xmlns", "a", "b", "uri", "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION }, + { NULL, "xmlns", "uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 }, + { "xmlns", NULL, "uri", NULL, "<e />", "<e", WR_E_XMLNSPREFIXDECLARATION, 0, 0, 1 }, + { "pre:fix", "local", "uri", "b", "<e />", "<e", WC_E_NAMECHARACTER }, + { "pre:fix", NULL, "uri", "b", "<e />", "<e", E_INVALIDARG }, + { "prefix", "lo:cal", "uri", "b", "<e />", "<e", WC_E_NAMECHARACTER }, + { "xmlns", NULL, NULL, "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED }, + { "xmlns", NULL, "", "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED }, + { "xmlns", "", NULL, "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED }, + { "xmlns", "", "", "uri", "<e />", "<e", WR_E_NSPREFIXDECLARED }, + { "xml", "space", "", "value", "<e />", "<e", WR_E_INVALIDXMLSPACE }, + { "xml", "space", NULL, "value", "<e />", "<e", WR_E_INVALIDXMLSPACE }, + { "xml", "a", "uri", "value", "<e />", "<e", WR_E_XMLPREFIXDECLARATION }, + { "xml", "space", NULL, "preServe", "<e />", "<e", WR_E_INVALIDXMLSPACE }, + { "xml", "space", NULL, "defAult", "<e />", "<e", WR_E_INVALIDXMLSPACE }, + { "xml", "space", NULL, NULL, "<e />", "<e", WR_E_INVALIDXMLSPACE }, + { "xml", "space", NULL, "", "<e />", "<e", WR_E_INVALIDXMLSPACE }, + }; + IXmlWriter *writer; IStream *stream; + unsigned int i; HRESULT hr;
hr = CreateXmlWriter(&IID_IXmlWriter, (void**)&writer, NULL); ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- stream = writer_set_output(writer); - writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration);
+ for (i = 0; i < ARRAY_SIZE(attribute_tests); ++i) + { + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); + ok(hr == S_OK, "Failed to start document, hr %#x.\n", hr); + + hr = write_start_element(writer, NULL, "e", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_attribute_string(writer, attribute_tests[i].prefix, attribute_tests[i].local, + attribute_tests[i].uri, attribute_tests[i].value); + todo_wine_if(attribute_tests[i].todo_hr) + ok(hr == attribute_tests[i].hr, "%u: unexpected hr %#x, expected %#x.\n", i, hr, attribute_tests[i].hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, attribute_tests[i].output_partial, attribute_tests[i].todo_partial, __LINE__); + + hr = IXmlWriter_WriteEndDocument(writer); + ok(hr == S_OK, "Failed to end document, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + check_output(stream, attribute_tests[i].output, attribute_tests[i].todo, __LINE__); + IStream_Release(stream); + } + + /* With namespaces */ + stream = writer_set_output(writer); + hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, "p", "a", "outeruri"); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = write_attribute_string(writer, "prefix", "local", "uri", "b"); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = write_attribute_string(writer, NULL, "a", NULL, "b"); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, bW); + hr = write_attribute_string(writer, "xmlns", "prefix", NULL, "uri"); ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = write_attribute_string(writer, "p", "attr", NULL, "value"); + ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr); + + hr = write_attribute_string(writer, "prefix", "local", NULL, "b"); +todo_wine + ok(hr == WR_E_DUPLICATEATTRIBUTE, "got 0x%08x\n", hr); + + hr = write_start_element(writer, NULL, "b", NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = write_attribute_string(writer, NULL, "attr2", "outeruri", "value"); + ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr); + + hr = write_attribute_string(writer, "pr", "attr3", "outeruri", "value"); + ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr); + hr = IXmlWriter_WriteEndDocument(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
- CHECK_OUTPUT(stream, - "<a a="b" />"); + CHECK_OUTPUT_TODO(stream, + "<p:a prefix:local="b" a="b" xmlns:prefix="uri" p:attr="value" xmlns:p="outeruri">" + "<b p:attr2="value" pr:attr3="value" xmlns:pr="outeruri" />" + "</p:a>"); + IStream_Release(stream);
- /* with namespaces */ + /* Define prefix, write attribute with it. */ stream = writer_set_output(writer);
hr = IXmlWriter_WriteStartDocument(writer, XmlStandalone_Omit); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteStartElement(writer, NULL, aW, NULL); + hr = write_start_element(writer, NULL, "e", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteAttributeString(writer, aW, NULL, NULL, bW); -todo_wine - ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, uriW, bW); -todo_wine + hr = write_attribute_string(writer, "xmlns", "prefix", NULL, "uri"); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteAttributeString(writer, NULL, aW, NULL, bW); + hr = write_attribute_string(writer, "prefix", "attr", NULL, "value"); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteAttributeString(writer, NULL, xmlnsW, uri2W, NULL); -todo_wine - ok(hr == WR_E_XMLNSPREFIXDECLARATION, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteAttributeString(writer, NULL, xmlnsW, NULL, uri2W); -todo_wine - ok(hr == WR_E_NSPREFIXDECLARED, "got 0x%08x\n", hr); - - hr = IXmlWriter_WriteAttributeString(writer, prefixW, localW, NULL, bW); -todo_wine - ok(hr == WR_E_DUPLICATEATTRIBUTE, "got 0x%08x\n", hr); - hr = IXmlWriter_WriteEndDocument(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_Flush(writer); ok(hr == S_OK, "got 0x%08x\n", hr);
- CHECK_OUTPUT_TODO(stream, - "<a prefix:local="b" a="b" xmlns:prefix="uri" />"); + CHECK_OUTPUT(stream, + "<e xmlns:prefix="uri" prefix:attr="value" />");
- IXmlWriter_Release(writer); IStream_Release(stream); + + IXmlWriter_Release(writer); }
static void test_WriteFullEndElement(void) @@ -1510,10 +1903,6 @@ static void test_WriteCharEntity(void)
static void test_WriteString(void) { - static const WCHAR markupW[] = {'<','&','"','>','=',0}; - static const WCHAR aW[] = {'a',0}; - static const WCHAR bW[] = {'b',0}; - static const WCHAR emptyW[] = {0}; IXmlWriter *writer; IStream *stream; HRESULT hr; @@ -1523,31 +1912,31 @@ static void test_WriteString(void)
writer_set_property(writer, XmlWriterProperty_OmitXmlDeclaration);
- hr = IXmlWriter_WriteString(writer, aW); + hr = write_string(writer, "a"); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, emptyW); + hr = write_string(writer, ""); ok(hr == E_UNEXPECTED, "got 0x%08x\n", hr);
stream = writer_set_output(writer);
- hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + hr = write_start_element(writer, NULL, "b", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, emptyW); + hr = write_string(writer, ""); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, aW); + hr = write_string(writer, "a"); ok(hr == S_OK, "got 0x%08x\n", hr);
/* WriteString automatically escapes markup characters */ - hr = IXmlWriter_WriteString(writer, markupW); + hr = write_string(writer, "<&">="); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_Flush(writer); @@ -1559,10 +1948,10 @@ static void test_WriteString(void)
stream = writer_set_output(writer);
- hr = IXmlWriter_WriteStartElement(writer, NULL, bW, NULL); + hr = write_start_element(writer, NULL, "b", NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = IXmlWriter_WriteString(writer, NULL); + hr = write_string(writer, NULL); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_Flush(writer); @@ -1571,7 +1960,7 @@ static void test_WriteString(void) CHECK_OUTPUT(stream, "<b");
- hr = IXmlWriter_WriteString(writer, emptyW); + hr = write_string(writer, ""); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IXmlWriter_Flush(writer); @@ -1580,18 +1969,257 @@ static void test_WriteString(void) CHECK_OUTPUT(stream, "<b>");
+ IStream_Release(stream); + IXmlWriter_Release(writer); + + /* With indentation */ + hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL); + ok(hr == S_OK, "Failed to create a writer, hr %#x.\n", hr); + + stream = writer_set_output(writer); + + writer_set_property(writer, XmlWriterProperty_Indent); + + hr = write_start_element(writer, NULL, "a", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_start_element(writer, NULL, "b", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_string(writer, "text"); + ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b>text"); + + hr = IXmlWriter_WriteFullEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b>text</b>"); + + hr = IXmlWriter_WriteFullEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b>text</b>\r\n" + "</a>"); + + IStream_Release(stream); + + stream = writer_set_output(writer); + + hr = write_start_element(writer, NULL, "a", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_start_element(writer, NULL, "b", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />"); + + hr = write_start_element(writer, NULL, "c", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_attribute_string(writer, NULL, "attr", NULL, "value"); + ok(hr == S_OK, "Failed to write attribute string, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value""); + + hr = write_string(writer, "text"); + ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text"); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>"); + + hr = write_start_element(writer, NULL, "d", NULL); + ok(hr == S_OK, "Failed to start element, hr %#x.\n", hr); + + hr = write_string(writer, ""); + ok(hr == S_OK, "Failed to write a string, hr %#x.\n", hr); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>\r\n" + " <d></d>"); + + hr = IXmlWriter_WriteEndElement(writer); + ok(hr == S_OK, "Failed to end element, hr %#x.\n", hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, + "<a>\r\n" + " <b />\r\n" + " <c attr="value">text</c>\r\n" + " <d></d>\r\n" + "</a>"); + IXmlWriter_Release(writer); IStream_Release(stream); }
+static HRESULT write_doctype(IXmlWriter *writer, const char *name, const char *pubid, const char *sysid, + const char *subset) +{ + WCHAR *nameW, *pubidW, *sysidW, *subsetW; + HRESULT hr; + + nameW = strdupAtoW(name); + pubidW = strdupAtoW(pubid); + sysidW = strdupAtoW(sysid); + subsetW = strdupAtoW(subset); + + hr = IXmlWriter_WriteDocType(writer, nameW, pubidW, sysidW, subsetW); + + heap_free(nameW); + heap_free(pubidW); + heap_free(sysidW); + heap_free(subsetW); + + return hr; +} + +static void test_WriteDocType(void) +{ + static const struct + { + const char *name; + const char *pubid; + const char *sysid; + const char *subset; + const char *output; + } + doctype_tests[] = + { + { "a", "", NULL, NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" }, + { "a", NULL, NULL, NULL, "<!DOCTYPE a>" }, + { "a", NULL, "", NULL, "<!DOCTYPE a SYSTEM \"\">" }, + { "a", "", "", NULL, "<!DOCTYPE a PUBLIC \"\" \"\">" }, + { "a", "pubid", "", NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" }, + { "a", "pubid", NULL, NULL, "<!DOCTYPE a PUBLIC \"pubid\" \"\">" }, + { "a", "", "sysid", NULL, "<!DOCTYPE a PUBLIC \"\" \"sysid\">" }, + { "a", NULL, NULL, "", "<!DOCTYPE a []>" }, + { "a", NULL, NULL, "subset", "<!DOCTYPE a [subset]>" }, + { "a", "", NULL, "subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" }, + { "a", NULL, "", "subset", "<!DOCTYPE a SYSTEM \"\" [subset]>" }, + { "a", "", "", "subset", "<!DOCTYPE a PUBLIC \"\" \"\" [subset]>" }, + { "a", "pubid", NULL, "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" }, + { "a", "pubid", "", "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"\" [subset]>" }, + { "a", NULL, "sysid", "subset", "<!DOCTYPE a SYSTEM \"sysid\" [subset]>" }, + { "a", "", "sysid", "subset", "<!DOCTYPE a PUBLIC \"\" \"sysid\" [subset]>" }, + { "a", "pubid", "sysid", "subset", "<!DOCTYPE a PUBLIC \"pubid\" \"sysid\" [subset]>" }, + }; + static const WCHAR pubidW[] = {'p',0x100,'i','d',0}; + static const WCHAR nameW[] = {'-','a',0}; + static const WCHAR emptyW[] = { 0 }; + IXmlWriter *writer; + IStream *stream; + unsigned int i; + HRESULT hr; + + hr = CreateXmlWriter(&IID_IXmlWriter, (void **)&writer, NULL); + ok(hr == S_OK, "Failed to create writer instance, hr %#x.\n", hr); + + stream = writer_set_output(writer); + + hr = IXmlWriter_WriteDocType(writer, NULL, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IXmlWriter_WriteDocType(writer, emptyW, NULL, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + /* Name validation. */ + hr = IXmlWriter_WriteDocType(writer, nameW, NULL, NULL, NULL); + ok(hr == WC_E_NAMECHARACTER, "Unexpected hr %#x.\n", hr); + + /* Pubid validation. */ + hr = IXmlWriter_WriteDocType(writer, aW, pubidW, NULL, NULL); + ok(hr == WC_E_PUBLICID, "Unexpected hr %#x.\n", hr); + + IStream_Release(stream); + + for (i = 0; i < ARRAY_SIZE(doctype_tests); i++) + { + stream = writer_set_output(writer); + + hr = write_doctype(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid, + doctype_tests[i].subset); + ok(hr == S_OK, "%u: failed to write doctype, hr %#x.\n", i, hr); + + hr = IXmlWriter_Flush(writer); + ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr); + + CHECK_OUTPUT(stream, doctype_tests[i].output); + + hr = write_doctype(writer, doctype_tests[i].name, doctype_tests[i].pubid, doctype_tests[i].sysid, + doctype_tests[i].subset); + ok(hr == WR_E_INVALIDACTION, "Unexpected hr %#x.\n", hr); + + IStream_Release(stream); + } + + IXmlWriter_Release(writer); +} + START_TEST(writer) { test_writer_create(); test_writer_state(); test_writeroutput(); test_writestartdocument(); - test_writestartelement(); - test_writeendelement(); + test_WriteStartElement(); + test_WriteElementString(); + test_WriteEndElement(); test_flush(); test_omitxmldeclaration(); test_bom(); @@ -1604,4 +2232,5 @@ START_TEST(writer) test_WriteFullEndElement(); test_WriteCharEntity(); test_WriteString(); + test_WriteDocType(); }