summaryrefslogtreecommitdiffstats
path: root/widget/windows/tests/gtest
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--widget/windows/tests/gtest/TestWinDND.cpp728
-rw-r--r--widget/windows/tests/gtest/moz.build18
2 files changed, 746 insertions, 0 deletions
diff --git a/widget/windows/tests/gtest/TestWinDND.cpp b/widget/windows/tests/gtest/TestWinDND.cpp
new file mode 100644
index 0000000000..fb7849fd79
--- /dev/null
+++ b/widget/windows/tests/gtest/TestWinDND.cpp
@@ -0,0 +1,728 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// #include <windows.h>
+#include <ole2.h>
+#include <shlobj.h>
+
+#include "nsArray.h"
+#include "nsArrayUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsIFile.h"
+#include "nsNetUtil.h"
+#include "nsISupportsPrimitives.h"
+#include "nsITransferable.h"
+
+#include "nsClipboard.h"
+#include "nsDataObjCollection.h"
+
+#include "gtest/gtest.h"
+
+// shims for conversion from cppunittest to gtest
+template <size_t N>
+void fail(const char (&msg)[N]) {
+ ADD_FAILURE() << "TEST-UNEXPECTED-FAIL | " << msg;
+}
+template <size_t N>
+void passed(const char (&msg)[N]) {
+ GTEST_SUCCEED() << "TEST-PASS | " << msg;
+}
+
+nsIFile* xferFile;
+
+nsresult CheckValidHDROP(STGMEDIUM* pSTG) {
+ if (pSTG->tymed != TYMED_HGLOBAL) {
+ fail("Received data is not in an HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ HGLOBAL hGlobal = pSTG->hGlobal;
+ DROPFILES* pDropFiles;
+ pDropFiles = (DROPFILES*)GlobalLock(hGlobal);
+ if (!pDropFiles) {
+ fail("There is no data at the given HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (pDropFiles->pFiles != sizeof(DROPFILES)) {
+ fail("DROPFILES struct has wrong size");
+ }
+
+ if (!pDropFiles->fWide) {
+ fail("Received data is not Unicode");
+ return NS_ERROR_UNEXPECTED;
+ }
+ nsString s;
+ unsigned long offset = 0;
+ while (true) {
+ s = (char16_t*)((char*)pDropFiles + pDropFiles->pFiles + offset);
+ if (s.IsEmpty()) break;
+ nsresult rv;
+ nsCOMPtr<nsIFile> localFile(
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
+ rv = localFile->InitWithPath(s);
+ if (NS_FAILED(rv)) {
+ fail("File could not be opened");
+ return NS_ERROR_UNEXPECTED;
+ }
+ offset += sizeof(char16_t) * (s.Length() + 1);
+ }
+ return NS_OK;
+}
+
+nsresult CheckValidTEXT(STGMEDIUM* pSTG) {
+ if (pSTG->tymed != TYMED_HGLOBAL) {
+ fail("Received data is not in an HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ HGLOBAL hGlobal = pSTG->hGlobal;
+ char* pText;
+ pText = (char*)GlobalLock(hGlobal);
+ if (!pText) {
+ fail("There is no data at the given HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsCString string;
+ string = pText;
+
+ if (!string.EqualsLiteral("Mozilla can drag and drop")) {
+ fail("Text passed through drop object wrong");
+ return NS_ERROR_UNEXPECTED;
+ }
+ return NS_OK;
+}
+
+nsresult CheckValidTEXTTwo(STGMEDIUM* pSTG) {
+ if (pSTG->tymed != TYMED_HGLOBAL) {
+ fail("Received data is not in an HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ HGLOBAL hGlobal = pSTG->hGlobal;
+ char* pText;
+ pText = (char*)GlobalLock(hGlobal);
+ if (!pText) {
+ fail("There is no data at the given HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsCString string;
+ string = pText;
+
+ if (!string.EqualsLiteral("Mozilla can drag and drop twice over")) {
+ fail("Text passed through drop object wrong");
+ return NS_ERROR_UNEXPECTED;
+ }
+ return NS_OK;
+}
+
+nsresult CheckValidUNICODE(STGMEDIUM* pSTG) {
+ if (pSTG->tymed != TYMED_HGLOBAL) {
+ fail("Received data is not in an HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ HGLOBAL hGlobal = pSTG->hGlobal;
+ char16_t* pText;
+ pText = (char16_t*)GlobalLock(hGlobal);
+ if (!pText) {
+ fail("There is no data at the given HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsString string;
+ string = pText;
+
+ if (!string.EqualsLiteral("Mozilla can drag and drop")) {
+ fail("Text passed through drop object wrong");
+ return NS_ERROR_UNEXPECTED;
+ }
+ return NS_OK;
+}
+
+nsresult CheckValidUNICODETwo(STGMEDIUM* pSTG) {
+ if (pSTG->tymed != TYMED_HGLOBAL) {
+ fail("Received data is not in an HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ HGLOBAL hGlobal = pSTG->hGlobal;
+ char16_t* pText;
+ pText = (char16_t*)GlobalLock(hGlobal);
+ if (!pText) {
+ fail("There is no data at the given HGLOBAL");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsString string;
+ string = pText;
+
+ if (!string.EqualsLiteral("Mozilla can drag and drop twice over")) {
+ fail("Text passed through drop object wrong");
+ return NS_ERROR_UNEXPECTED;
+ }
+ return NS_OK;
+}
+
+nsresult GetTransferableFile(nsCOMPtr<nsITransferable>& pTransferable) {
+ nsresult rv;
+
+ nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferFile);
+
+ pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
+ pTransferable->Init(nullptr);
+ rv = pTransferable->SetTransferData("application/x-moz-file", genericWrapper);
+ return rv;
+}
+
+nsresult GetTransferableText(nsCOMPtr<nsITransferable>& pTransferable) {
+ nsresult rv;
+ constexpr auto mozString = u"Mozilla can drag and drop"_ns;
+ nsCOMPtr<nsISupportsString> xferString =
+ do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+ rv = xferString->SetData(mozString);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString);
+
+ pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
+ pTransferable->Init(nullptr);
+ rv = pTransferable->SetTransferData("text/plain", genericWrapper);
+ return rv;
+}
+
+nsresult GetTransferableTextTwo(nsCOMPtr<nsITransferable>& pTransferable) {
+ nsresult rv;
+ constexpr auto mozString = u" twice over"_ns;
+ nsCOMPtr<nsISupportsString> xferString =
+ do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
+ rv = xferString->SetData(mozString);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString);
+
+ pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
+ pTransferable->Init(nullptr);
+ rv = pTransferable->SetTransferData("text/plain", genericWrapper);
+ return rv;
+}
+
+nsresult GetTransferableURI(nsCOMPtr<nsITransferable>& pTransferable) {
+ nsresult rv;
+
+ nsCOMPtr<nsIURI> xferURI;
+
+ rv = NS_NewURI(getter_AddRefs(xferURI), "http://www.mozilla.org");
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferURI);
+
+ pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1");
+ pTransferable->Init(nullptr);
+ rv = pTransferable->SetTransferData("text/x-moz-url", genericWrapper);
+ return rv;
+}
+
+nsresult MakeDataObject(nsIArray* transferableArray,
+ RefPtr<IDataObject>& itemToDrag) {
+ nsresult rv;
+ uint32_t itemCount = 0;
+
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewURI(getter_AddRefs(uri), "http://www.mozilla.org");
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = transferableArray->GetLength(&itemCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Copied more or less exactly from nsDragService::InvokeDragSession
+ // This is what lets us play fake Drag Service for the test
+ if (itemCount > 1) {
+ nsDataObjCollection* dataObjCollection = new nsDataObjCollection();
+ if (!dataObjCollection) return NS_ERROR_OUT_OF_MEMORY;
+ itemToDrag = dataObjCollection;
+ for (uint32_t i = 0; i < itemCount; ++i) {
+ nsCOMPtr<nsITransferable> trans = do_QueryElementAt(transferableArray, i);
+ if (trans) {
+ RefPtr<IDataObject> dataObj;
+ rv = nsClipboard::CreateNativeDataObject(trans, getter_AddRefs(dataObj),
+ uri);
+ NS_ENSURE_SUCCESS(rv, rv);
+ // Add the flavors to the collection object too
+ rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ dataObjCollection->AddDataObject(dataObj);
+ }
+ }
+ } // if dragging multiple items
+ else {
+ nsCOMPtr<nsITransferable> trans = do_QueryElementAt(transferableArray, 0);
+ if (trans) {
+ rv = nsClipboard::CreateNativeDataObject(trans,
+ getter_AddRefs(itemToDrag), uri);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ } // else dragging a single object
+ return rv;
+}
+
+nsresult Do_CheckOneFile() {
+ nsresult rv;
+ nsCOMPtr<nsITransferable> transferable;
+ nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create();
+ nsCOMPtr<nsISupports> genericWrapper;
+ RefPtr<IDataObject> dataObj;
+
+ rv = GetTransferableFile(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = MakeDataObject(transferableArray, dataObj);
+ if (NS_FAILED(rv)) {
+ fail("Could not create data object");
+ return rv;
+ }
+
+ FORMATETC fe;
+ SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("File data object does not support the file data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ STGMEDIUM* stg;
+ stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("File data object did not provide data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidHDROP(stg);
+ if (NS_FAILED(rv)) {
+ fail("HDROP was invalid");
+ return rv;
+ }
+
+ ReleaseStgMedium(stg);
+
+ return NS_OK;
+}
+
+nsresult Do_CheckTwoFiles() {
+ nsresult rv;
+ nsCOMPtr<nsITransferable> transferable;
+ nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create();
+ nsCOMPtr<nsISupports> genericWrapper;
+ RefPtr<IDataObject> dataObj;
+
+ rv = GetTransferableFile(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = GetTransferableFile(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = MakeDataObject(transferableArray, dataObj);
+ if (NS_FAILED(rv)) {
+ fail("Could not create data object");
+ return rv;
+ }
+
+ FORMATETC fe;
+ SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("File data object does not support the file data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ STGMEDIUM* stg;
+ stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("File data object did not provide data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidHDROP(stg);
+ if (NS_FAILED(rv)) {
+ fail("HDROP was invalid");
+ return rv;
+ }
+
+ ReleaseStgMedium(stg);
+
+ return NS_OK;
+}
+
+nsresult Do_CheckOneString() {
+ nsresult rv;
+ nsCOMPtr<nsITransferable> transferable;
+ nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create();
+ nsCOMPtr<nsISupports> genericWrapper;
+ RefPtr<IDataObject> dataObj;
+
+ rv = GetTransferableText(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = MakeDataObject(transferableArray, dataObj);
+ if (NS_FAILED(rv)) {
+ fail("Could not create data object");
+ return rv;
+ }
+
+ FORMATETC fe;
+ SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("String data object does not support the ASCII text data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ STGMEDIUM* stg;
+ stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("String data object did not provide ASCII data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidTEXT(stg);
+ if (NS_FAILED(rv)) {
+ fail("TEXT was invalid");
+ return rv;
+ }
+
+ ReleaseStgMedium(stg);
+
+ SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("String data object does not support the wide text data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("String data object did not provide wide data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidUNICODE(stg);
+ if (NS_FAILED(rv)) {
+ fail("UNICODE was invalid");
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+nsresult Do_CheckTwoStrings() {
+ nsresult rv;
+ nsCOMPtr<nsITransferable> transferable;
+ nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create();
+ nsCOMPtr<nsISupports> genericWrapper;
+ RefPtr<IDataObject> dataObj;
+
+ rv = GetTransferableText(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = GetTransferableTextTwo(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ rv = MakeDataObject(transferableArray, dataObj);
+ if (NS_FAILED(rv)) {
+ fail("Could not create data object");
+ return rv;
+ }
+
+ FORMATETC fe;
+ SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("String data object does not support the ASCII text data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ STGMEDIUM* stg;
+ stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("String data object did not provide ASCII data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidTEXTTwo(stg);
+ if (NS_FAILED(rv)) {
+ fail("TEXT was invalid");
+ return rv;
+ }
+
+ ReleaseStgMedium(stg);
+
+ SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("String data object does not support the wide text data type!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (dataObj->GetData(&fe, stg) != S_OK) {
+ fail("String data object did not provide wide data on request");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ rv = CheckValidUNICODETwo(stg);
+ if (NS_FAILED(rv)) {
+ fail("UNICODE was invalid");
+ return rv;
+ }
+
+ return NS_OK;
+}
+
+nsresult Do_CheckSetArbitraryData(bool aMultiple) {
+ nsresult rv;
+ nsCOMPtr<nsITransferable> transferable;
+ nsCOMPtr<nsIMutableArray> transferableArray = nsArray::Create();
+ nsCOMPtr<nsISupports> genericWrapper;
+ RefPtr<IDataObject> dataObj;
+
+ rv = GetTransferableText(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+
+ if (aMultiple) {
+ rv = GetTransferableText(transferable);
+ if (NS_FAILED(rv)) {
+ fail("Could not create the proper nsITransferable!");
+ return rv;
+ }
+ genericWrapper = do_QueryInterface(transferable);
+ rv = transferableArray->AppendElement(genericWrapper);
+ if (NS_FAILED(rv)) {
+ fail("Could not append element to transferable array");
+ return rv;
+ }
+ }
+
+ rv = MakeDataObject(transferableArray, dataObj);
+ if (NS_FAILED(rv)) {
+ fail("Could not create data object");
+ return rv;
+ }
+
+ static CLIPFORMAT mozArbitraryFormat =
+ ::RegisterClipboardFormatW(L"MozillaTestFormat");
+ FORMATETC fe;
+ STGMEDIUM stg;
+ SET_FORMATETC(fe, mozArbitraryFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
+
+ HGLOBAL hg = GlobalAlloc(GPTR, 1024);
+ stg.tymed = TYMED_HGLOBAL;
+ stg.hGlobal = hg;
+ stg.pUnkForRelease = nullptr;
+
+ if (dataObj->SetData(&fe, &stg, true) != S_OK) {
+ if (aMultiple) {
+ fail("Unable to set arbitrary data type on data object collection!");
+ } else {
+ fail("Unable to set arbitrary data type on data object!");
+ }
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (dataObj->QueryGetData(&fe) != S_OK) {
+ fail("Arbitrary data set on data object is not advertised!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ STGMEDIUM* stg2;
+ stg2 = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM));
+ if (dataObj->GetData(&fe, stg2) != S_OK) {
+ fail("Data object did not provide arbitrary data upon request!");
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ if (stg2->hGlobal != hg) {
+ fail("Arbitrary data was not returned properly!");
+ return rv;
+ }
+ ReleaseStgMedium(stg2);
+
+ return NS_OK;
+}
+
+// This function performs basic drop tests, testing a data object consisting
+// of one transferable
+nsresult Do_Test1() {
+ nsresult rv = NS_OK;
+ nsresult workingrv;
+
+ workingrv = Do_CheckOneFile();
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on a single file");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully created a working file drag object!");
+ }
+
+ workingrv = Do_CheckOneString();
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on a single string");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully created a working string drag object!");
+ }
+
+ workingrv = Do_CheckSetArbitraryData(false);
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on setting arbitrary data");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully set arbitrary data on a drag object");
+ }
+
+ return rv;
+}
+
+// This function performs basic drop tests, testing a data object consisting of
+// two transferables.
+nsresult Do_Test2() {
+ nsresult rv = NS_OK;
+ nsresult workingrv;
+
+ workingrv = Do_CheckTwoFiles();
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on multiple files");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully created a working multiple file drag object!");
+ }
+
+ workingrv = Do_CheckTwoStrings();
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on multiple strings");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully created a working multiple string drag object!");
+ }
+
+ workingrv = Do_CheckSetArbitraryData(true);
+ if (NS_FAILED(workingrv)) {
+ fail("Drag object tests failed on setting arbitrary data");
+ rv = NS_ERROR_UNEXPECTED;
+ } else {
+ passed("Successfully set arbitrary data on a drag object");
+ }
+
+ return rv;
+}
+
+// This function performs advanced drag and drop tests, testing a data object
+// consisting of multiple transferables that have different data types
+nsresult Do_Test3() {
+ nsresult rv = NS_OK;
+ // nsresult workingrv;
+
+ // XXX TODO Write more advanced tests in Bug 535860
+ return rv;
+}
+
+nsCOMPtr<nsIFile> GetTemporaryDirectory() {
+ nsCOMPtr<nsIFile> tmpdir;
+
+#define ENSURE(expr) NS_ENSURE_SUCCESS(expr, nullptr);
+
+ ENSURE(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpdir)));
+ MOZ_ASSERT(tmpdir);
+
+ ENSURE(tmpdir->AppendNative("TestWinDND"_ns));
+ ENSURE(tmpdir->CreateUnique(nsIFile::DIRECTORY_TYPE, 0777));
+
+#undef ENSURE
+
+ return tmpdir;
+}
+
+TEST(TestWinDND, All)
+{
+ nsCOMPtr<nsIFile> file = GetTemporaryDirectory();
+ if (!file) {
+ fail("could not create temporary directory!");
+ return;
+ }
+ xferFile = file;
+
+ if (NS_SUCCEEDED(Do_Test1())) {
+ passed(
+ "Basic Drag and Drop data type tests (single transferable) succeeded!");
+ }
+
+ if (NS_SUCCEEDED(Do_Test2())) {
+ passed(
+ "Basic Drag and Drop data type tests (multiple transferables) "
+ "succeeded!");
+ }
+
+ // if (NS_SUCCEEDED(Do_Test3()))
+ // passed("Advanced Drag and Drop data type tests succeeded!");
+}
diff --git a/widget/windows/tests/gtest/moz.build b/widget/windows/tests/gtest/moz.build
new file mode 100644
index 0000000000..c49c6fe296
--- /dev/null
+++ b/widget/windows/tests/gtest/moz.build
@@ -0,0 +1,18 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+UNIFIED_SOURCES += [
+ "TestWinDND.cpp",
+]
+
+LOCAL_INCLUDES += [
+ "/widget",
+ "/widget/windows",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul-gtest"