diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 93d134ac0c6..59b77a77791 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -33,12 +33,125 @@ static const char doc_blank[] = ""; static const char doc_str1[] = "test"; static const char doc_str2[] = "test abc 123
it's
text
"; +static const char doc_str3[] = + "test" + "link" + "" + "" + ""; static const WCHAR noneW[] = {'N','o','n','e',0}; static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0}; static WCHAR wordW[] = {'w','o','r','d',0}; +typedef enum { + ET_NONE, + ET_HTML, + ET_HEAD, + ET_TITLE, + ET_BODY, + ET_A, + ET_INPUT, + ET_SELECT, + ET_TEXTAREA, + ET_OPTION +} elem_type_t; + +static const REFIID none_iids[] = { + &IID_IUnknown, + NULL +}; + +static const REFIID html_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + NULL +}; + +static const REFIID head_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + NULL +}; + +static const REFIID title_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + NULL +}; + +static const REFIID body_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLTextContainer, + &IID_IHTMLBodyElement, + NULL +}; + +static const REFIID anchor_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLAnchorElement, + NULL +}; + +static const REFIID input_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLInputElement, + &IID_IHTMLInputTextElement, + NULL +}; + +static const REFIID select_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLSelectElement, + NULL +}; + +static const REFIID textarea_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLTextAreaElement, + NULL +}; + +static const REFIID option_iids[] = { + &IID_IHTMLDOMNode, + &IID_IHTMLElement, + &IID_IHTMLElement2, + &IID_IHTMLOptionElement, + NULL +}; + +typedef struct { + const char *tag; + REFIID *iids; +} elem_type_info_t; + +static const elem_type_info_t elem_type_infos[] = { + {"", none_iids}, + {"HTML", html_iids}, + {"HEAD", head_iids}, + {"TITLE", title_iids}, + {"BODY", body_iids}, + {"A", anchor_iids}, + {"INPUT", input_iids}, + {"SELECT", select_iids}, + {"TEXTAREA", textarea_iids}, + {"OPTION", option_iids} +}; + static const char *dbgstr_w(LPCWSTR str) { static char buf[512]; @@ -48,6 +161,18 @@ static const char *dbgstr_w(LPCWSTR str) return buf; } +static const char *dbgstr_guid(REFIID riid) +{ + static char buf[50]; + + sprintf(buf, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + riid->Data1, riid->Data2, riid->Data3, riid->Data4[0], + riid->Data4[1], riid->Data4[2], riid->Data4[3], riid->Data4[4], + riid->Data4[5], riid->Data4[6], riid->Data4[7]); + + return buf; +} + static int strcmp_wa(LPCWSTR strw, const char *stra) { WCHAR buf[512]; @@ -55,6 +180,18 @@ static int strcmp_wa(LPCWSTR strw, const char *stra) return lstrcmpW(strw, buf); } +static BSTR a2bstr(const char *str) +{ + BSTR ret; + int len; + + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + ret = SysAllocStringLen(NULL, len); + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len); + + return ret; +} + static IHTMLDocument2 *create_document(void) { IHTMLDocument2 *doc; @@ -67,6 +204,21 @@ static IHTMLDocument2 *create_document(void) return doc; } +#define test_ifaces(i,ids) _test_ifaces(__LINE__,i,ids) +static void _test_ifaces(unsigned line, IUnknown *iface, REFIID *iids) +{ + const IID * const *piid; + IUnknown *unk; + HRESULT hres; + + for(piid = iids; *piid; piid++) { + hres = IDispatch_QueryInterface(iface, *piid, (void**)&unk); + ok_(__FILE__,line) (hres == S_OK, "Could not get %s interface: %08x\n", dbgstr_guid(*piid), hres); + if(SUCCEEDED(hres)) + IUnknown_Release(unk); + } +} + #define test_node_name(u,n) _test_node_name(__LINE__,u,n) static void _test_node_name(unsigned line, IUnknown *unk, const char *exname) { @@ -103,6 +255,13 @@ static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag) SysFreeString(tag); } +#define test_elem_type(ifc,t) _test_elem_type(__LINE__,ifc,t) +static void _test_elem_type(unsigned line, IUnknown *unk, elem_type_t type) +{ + _test_elem_tag(line, unk, elem_type_infos[type].tag); + _test_ifaces(line, unk, elem_type_infos[type].iids); +} + static void test_doc_elem(IHTMLDocument2 *doc) { IHTMLElement *elem; @@ -122,6 +281,142 @@ static void test_doc_elem(IHTMLDocument2 *doc) IHTMLElement_Release(elem); } +#define get_doc_elem(d) _get_doc_elem(__LINE__,d) +static IHTMLElement *_get_doc_elem(unsigned line, IHTMLDocument2 *doc) +{ + IHTMLElement *elem; + IHTMLDocument3 *doc3; + HRESULT hres; + + hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument3, (void**)&doc3); + ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDocument3 interface: %08x\n", hres); + hres = IHTMLDocument3_get_documentElement(doc3, &elem); + ok_(__FILE__,line) (hres == S_OK, "get_documentElement failed: %08x\n", hres); + IHTMLDocument3_Release(doc3); + + return elem; +} + +#define test_option_text(o,t) _test_option_text(__LINE__,o,t) +static void _test_option_text(unsigned line, IHTMLOptionElement *option, const char *text) +{ + BSTR bstr; + HRESULT hres; + + hres = IHTMLOptionElement_get_text(option, &bstr); + ok_(__FILE__,line) (hres == S_OK, "get_text failed: %08x\n", hres); + ok_(__FILE__,line) (!strcmp_wa(bstr, text), "text=%s\n", dbgstr_w(bstr)); + SysFreeString(bstr); +} + +#define test_option_put_text(o,t) _test_option_put_text(__LINE__,o,t) +static void _test_option_put_text(unsigned line, IHTMLOptionElement *option, const char *text) +{ + BSTR bstr; + HRESULT hres; + + bstr = a2bstr(text); + hres = IHTMLOptionElement_put_text(option, bstr); + SysFreeString(bstr); + ok(hres == S_OK, "put_text failed: %08x\n", hres); + + _test_option_text(line, option, text); +} + +#define test_option_value(o,t) _test_option_value(__LINE__,o,t) +static void _test_option_value(unsigned line, IHTMLOptionElement *option, const char *value) +{ + BSTR bstr; + HRESULT hres; + + hres = IHTMLOptionElement_get_value(option, &bstr); + ok_(__FILE__,line) (hres == S_OK, "get_value failed: %08x\n", hres); + ok_(__FILE__,line) (!strcmp_wa(bstr, value), "value=%s\n", dbgstr_w(bstr)); + SysFreeString(bstr); +} + +#define test_option_put_value(o,t) _test_option_put_value(__LINE__,o,t) +static void _test_option_put_value(unsigned line, IHTMLOptionElement *option, const char *value) +{ + BSTR bstr; + HRESULT hres; + + bstr = a2bstr(value); + hres = IHTMLOptionElement_put_value(option, bstr); + SysFreeString(bstr); + ok(hres == S_OK, "put_value failed: %08x\n", hres); + + _test_option_value(line, option, value); +} + +#define create_option_elem(d,t,v) _create_option_elem(__LINE__,d,t,v) +static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *doc, + const char *txt, const char *val) +{ + IHTMLOptionElementFactory *factory; + IHTMLOptionElement *option; + IHTMLWindow2 *window; + VARIANT text, value, empty; + HRESULT hres; + + hres = IHTMLDocument2_get_parentWindow(doc, &window); + ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres); + + hres = IHTMLWindow2_get_Option(window, &factory); + IHTMLWindow2_Release(window); + ok_(__FILE__,line) (hres == S_OK, "get_Option failed: %08x\n", hres); + + V_VT(&text) = VT_BSTR; + V_BSTR(&text) = a2bstr(txt); + V_VT(&value) = VT_BSTR; + V_BSTR(&value) = a2bstr(val); + V_VT(&empty) = VT_EMPTY; + + hres = IHTMLOptionElementFactory_create(factory, text, value, empty, empty, &option); + ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres); + + IHTMLOptionElementFactory_Release(factory); + VariantClear(&text); + VariantClear(&value); + + _test_option_text(line, option, txt); + _test_option_value(line, option, val); + + return option; +} + +#define test_select_length(s,l) _test_select_length(__LINE__,s,l) +static void _test_select_length(unsigned line, IHTMLSelectElement *select, long length) +{ + long len = 0xdeadbeef; + HRESULT hres; + + hres = IHTMLSelectElement_get_length(select, &len); + ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres); + ok_(__FILE__,line) (len == length, "len=%ld, expected %ld\n", len, length); +} + +#define test_select_selidx(s,i) _test_select_selidx(__LINE__,s,i) +static void _test_select_selidx(unsigned line, IHTMLSelectElement *select, long index) +{ + long idx = 0xdeadbeef; + HRESULT hres; + + hres = IHTMLSelectElement_get_selectedIndex(select, &idx); + ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres); + ok_(__FILE__,line) (idx == index, "idx=%ld, expected %ld\n", idx, index); +} + +#define test_select_put_selidx(s,i) _test_select_put_selidx(__LINE__,s,i) +static void _test_select_put_selidx(unsigned line, IHTMLSelectElement *select, long index) +{ + HRESULT hres; + + hres = IHTMLSelectElement_put_selectedIndex(select, index); + ok_(__FILE__,line) (hres == S_OK, "get_selectedIndex failed: %08x\n", hres); + _test_select_selidx(line, select, index); +} + #define test_range_text(r,t) _test_range_text(__LINE__,r,t) static void _test_range_text(unsigned line, IHTMLTxtRange *range, const char *extext) { @@ -232,6 +527,157 @@ static void _test_range_isequal(unsigned line, IHTMLTxtRange *range1, IHTMLTxtRa } } +static void test_elem_collection(IHTMLElementCollection *col, const elem_type_t *elem_types, long exlen) +{ + long len; + DWORD i; + VARIANT name, index; + IDispatch *disp; + HRESULT hres; + + hres = IHTMLElementCollection_get_length(col, &len); + ok(hres == S_OK, "get_length failed: %08x\n", hres); + ok(len == exlen, "len=%ld, expected %ld\n", len, exlen); + + V_VT(&index) = VT_EMPTY; + V_VT(&name) = VT_I4; + + for(i=0; i