Enable WebSocket resource unit tests. (#2415)

* Define test WebSocket types.

* Use CRLF for C++ files.

* Try basic_stream_socket over IWebSocketStream.

* Use boost::beast::test::stream.

* Defined async_connect(test::stream& ...

* Move custom async_connect into WebSocket.cpp.

* Defined MockStreamLayer subtype.

* Use errc::make_error_code.

* Define MockStream, equivalent to websocket::stream

* Implement async read and write in MockStreamLayer.

* Override boost::beast::http::async_read and write.

* Move TestWebSocket implementation to CPP file.

* Stop including <boost/beast/experimental/test/stream.hpp>.

* Simplify template decls for SecureWebSocket.

* Simplified WebSocket template declaration.

* Updated namespace for WebSocket-related APIs.

* Reset default platform to x64 in SLN.

* Re-located BaseWebSocketTest.
This commit is contained in:
Julio César Rocha 2019-05-06 14:49:32 -07:00 коммит произвёл GitHub
Родитель 02893fc709
Коммит f8c9e20cf0
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
21 изменённых файлов: 478 добавлений и 70 удалений

7
.gitattributes поставляемый
Просмотреть файл

@ -2,9 +2,12 @@
# Auto detect text files and perform LF normalization
* text=auto
*.cpp -text
*.h -text
# C++ files should use CRLF.
*.c text eol=crlf
*.cpp text eol=crlf
*.h text eol=crlf
*.hpp text eol=crlf
# Force Visual Studio project files (mostly XML) to CRLF
# This helps avoid conflict which occurs when Xmarian/Mac contributors with AutoCRLF=input (or off)

Просмотреть файл

@ -10,6 +10,9 @@ insert_final_newline = true
indent_style = space
indent_size = 2
[*.{c,cpp,h,hpp}]
end_of_line = crlf
# Xml project files
[*.{csproj,vcxproj,pssproj,vcxproj.filters,targets,props}]
end_of_line = crlf

Просмотреть файл

@ -17,7 +17,7 @@ EXPORTS
?CreateMemoryTracker@react@facebook@@YA?AV?$shared_ptr@VMemoryTracker@react@facebook@@@std@@$$QEAV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?CreateTimingModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@AEBV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?CreateWebSocketModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?CreateWebSocketModule@React@Microsoft@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?destroy@dynamic@folly@@AEAAXXZ
?dispatchCommand@ShadowNode@react@facebook@@UEAAX_JAEBUdynamic@folly@@@Z
?GetConstants@ViewManagerBase@react@facebook@@UEBA?AUdynamic@folly@@XZ
@ -25,7 +25,7 @@ EXPORTS
?InitializeLogging@react@facebook@@YAX$$QEAV?$function@$$A6AXW4RCTLogLevel@react@facebook@@PEBD@Z@std@@@Z
?InitializeTracing@react@facebook@@YAXPEAUINativeTraceHandler@12@@Z
?Make@IHttpResource@react@facebook@@SA?AV?$unique_ptr@UIHttpResource@react@facebook@@U?$default_delete@UIHttpResource@react@facebook@@@std@@@std@@XZ
?Make@IWebSocket@react@facebook@@SA?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IWebSocket@React@Microsoft@@SA?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@JSBigAbiString@react@facebook@@SA?AV?$unique_ptr@$$CBUJSBigAbiString@react@facebook@@U?$default_delete@$$CBUJSBigAbiString@react@facebook@@@std@@@std@@$$QEAV?$unique_ptr@U?$IAbiArray@D@AbiSafe@@UAbiObjectDeleter@2@@5@@Z
?Make@JSBigStringResourceDll@react@facebook@@SA?AV?$unique_ptr@$$CBVJSBigStringResourceDll@react@facebook@@U?$default_delete@$$CBVJSBigStringResourceDll@react@facebook@@@std@@@std@@PEAUHINSTANCE__@@PEAUHRSRC__@@@Z
?makeConversionError@folly@@YA?AVConversionError@1@W4ConversionCode@1@V?$Range@PEBD@1@@Z

Просмотреть файл

@ -17,7 +17,7 @@ EXPORTS
?CreateMemoryTracker@react@facebook@@YG?AV?$shared_ptr@VMemoryTracker@react@facebook@@@std@@$$QAV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?CreateTimingModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@ABV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?CreateWebSocketModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?CreateWebSocketModule@rReact@Microsoft@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?destroy@dynamic@folly@@AAEXXZ
?dispatchCommand@ShadowNode@react@facebook@@UAEX_JABUdynamic@folly@@@Z
?GetConstants@ViewManagerBase@react@facebook@@UBE?AUdynamic@folly@@XZ
@ -34,7 +34,7 @@ EXPORTS
?Utf16ToUtf8@UnicodeConversion@react@facebook@@YG?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@5@@Z
?Utf8ToUtf16@UnicodeConversion@react@facebook@@YG?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IHttpResource@react@facebook@@SG?AV?$unique_ptr@UIHttpResource@react@facebook@@U?$default_delete@UIHttpResource@react@facebook@@@std@@@std@@XZ
?Make@IWebSocket@react@facebook@@SG?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IWebSocket@React@Microsoft@@SG?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@JSBigAbiString@react@facebook@@SG?AV?$unique_ptr@$$CBUJSBigAbiString@react@facebook@@U?$default_delete@$$CBUJSBigAbiString@react@facebook@@@std@@@std@@$$QAV?$unique_ptr@U?$IAbiArray@D@AbiSafe@@UAbiObjectDeleter@2@@5@@Z
?Make@JSBigStringResourceDll@react@facebook@@SG?AV?$unique_ptr@$$CBVJSBigStringResourceDll@react@facebook@@U?$default_delete@$$CBVJSBigStringResourceDll@react@facebook@@@std@@@std@@PAUHINSTANCE__@@PAUHRSRC__@@@Z

Просмотреть файл

@ -20,7 +20,7 @@ EXPORTS
?CreateReactInstance@react@facebook@@YA?AV?$shared_ptr@UInstanceWrapper@react@facebook@@@std@@$$QEAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@4@0$$QEAV?$vector@V?$tuple@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$function@$$A6A?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ@2@V?$shared_ptr@VMessageQueueThread@react@facebook@@@2@@std@@V?$allocator@V?$tuple@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$function@$$A6A?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ@2@V?$shared_ptr@VMessageQueueThread@react@facebook@@@2@@std@@@2@@4@V?$shared_ptr@VIUIManager@react@facebook@@@4@V?$shared_ptr@VMessageQueueThread@react@facebook@@@4@3V?$shared_ptr@UDevSettings@react@facebook@@@4@@Z
?CreateTimingModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@AEBV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?CreateWebSocketModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?CreateWebSocketModule@React@Microsoft@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?destroy@dynamic@folly@@AEAAXXZ
?dispatchCommand@ShadowNode@react@facebook@@UEAAX_JAEBUdynamic@folly@@@Z
?GetConstants@ViewManagerBase@react@facebook@@UEBA?AUdynamic@folly@@XZ
@ -30,11 +30,11 @@ EXPORTS
?InitializeTracing@react@facebook@@YAXPEAUINativeTraceHandler@12@@Z
?loadScriptFromString@Instance@react@facebook@@UEAAXV?$unique_ptr@$$CBVJSBigString@react@facebook@@U?$default_delete@$$CBVJSBigString@react@facebook@@@std@@@std@@_KV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@_N$$QEAV65@@Z
?Make@IHttpResource@react@facebook@@SA?AV?$unique_ptr@UIHttpResource@react@facebook@@U?$default_delete@UIHttpResource@react@facebook@@@std@@@std@@XZ
?Make@IWebSocket@react@facebook@@SA?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IWebSocket@React@Microsoft@@SA?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@JSBigAbiString@react@facebook@@SA?AV?$unique_ptr@$$CBUJSBigAbiString@react@facebook@@U?$default_delete@$$CBUJSBigAbiString@react@facebook@@@std@@@std@@$$QEAV?$unique_ptr@U?$IAbiArray@D@AbiSafe@@UAbiObjectDeleter@2@@5@@Z
?Make@JSBigStringResourceDll@react@facebook@@SA?AV?$unique_ptr@$$CBVJSBigStringResourceDll@react@facebook@@U?$default_delete@$$CBVJSBigStringResourceDll@react@facebook@@@std@@@std@@PEAUHINSTANCE__@@PEAUHRSRC__@@@Z
?makeConversionError@folly@@YA?AVConversionError@1@W4ConversionCode@1@V?$Range@PEBD@1@@Z
?MakeLegacy@IWebSocket@react@facebook@@SA?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?MakeLegacy@IWebSocket@React@Microsoft@@SA?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?parseJson@folly@@YA?AUdynamic@1@V?$Range@PEBD@1@@Z
?setGlobalVariable@Instance@react@facebook@@UEAAXV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$unique_ptr@$$CBVJSBigString@react@facebook@@U?$default_delete@$$CBVJSBigString@react@facebook@@@std@@@5@@Z
?size@dynamic@folly@@QEBA_KXZ

Просмотреть файл

@ -20,7 +20,7 @@ EXPORTS
?CreateReactInstance@react@facebook@@YG?AV?$shared_ptr@UInstanceWrapper@react@facebook@@@std@@$$QAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@4@0$$QAV?$vector@V?$tuple@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$function@$$A6G?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ@2@V?$shared_ptr@VMessageQueueThread@react@facebook@@@2@@std@@V?$allocator@V?$tuple@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$function@$$A6G?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ@2@V?$shared_ptr@VMessageQueueThread@react@facebook@@@2@@std@@@2@@4@V?$shared_ptr@VIUIManager@react@facebook@@@4@V?$shared_ptr@VMessageQueueThread@react@facebook@@@4@3V?$shared_ptr@UDevSettings@react@facebook@@@4@@Z
?CreateTimingModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@ABV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?CreateWebSocketModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?CreateWebSocketModule@React@Microsoft@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?destroy@dynamic@folly@@AAEXXZ
?dispatchCommand@ShadowNode@react@facebook@@UAEX_JABUdynamic@folly@@@Z
?GetConstants@ViewManagerBase@react@facebook@@UBE?AUdynamic@folly@@XZ
@ -40,10 +40,10 @@ EXPORTS
?Utf16ToUtf8@UnicodeConversion@react@facebook@@YG?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@5@@Z
?Utf8ToUtf16@UnicodeConversion@react@facebook@@YG?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IHttpResource@react@facebook@@SG?AV?$unique_ptr@UIHttpResource@react@facebook@@U?$default_delete@UIHttpResource@react@facebook@@@std@@@std@@XZ
?Make@IWebSocket@react@facebook@@SG?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IWebSocket@React@Microsoft@@SG?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@JSBigAbiString@react@facebook@@SG?AV?$unique_ptr@$$CBUJSBigAbiString@react@facebook@@U?$default_delete@$$CBUJSBigAbiString@react@facebook@@@std@@@std@@$$QAV?$unique_ptr@U?$IAbiArray@D@AbiSafe@@UAbiObjectDeleter@2@@5@@Z
?Make@JSBigStringResourceDll@react@facebook@@SG?AV?$unique_ptr@$$CBVJSBigStringResourceDll@react@facebook@@U?$default_delete@$$CBVJSBigStringResourceDll@react@facebook@@@std@@@std@@PAUHINSTANCE__@@PAUHRSRC__@@@Z
?MakeLegacy@IWebSocket@react@facebook@@SG?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?MakeLegacy@IWebSocket@React@Microsoft@@SG?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
YGLog
YGLogWithConfig

Просмотреть файл

@ -15,7 +15,7 @@ EXPORTS
?createIUIManager@react@facebook@@YA?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PAUINativeUIManager@12@@Z
?CreateTimingModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@ABV?$shared_ptr@VMessageQueueThread@react@facebook@@@4@@Z
?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?CreateWebSocketModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?CreateWebSocketModule@React@Microsoft@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@XZ
?destroy@dynamic@folly@@AAEXXZ
?dispatchCommand@ShadowNode@react@facebook@@UAEX_JABUdynamic@folly@@@Z
?GetConstants@ViewManagerBase@react@facebook@@UBE?AUdynamic@folly@@XZ
@ -31,7 +31,7 @@ EXPORTS
?Utf16ToUtf8@UnicodeConversion@react@facebook@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@5@@Z
?Utf8ToUtf16@UnicodeConversion@react@facebook@@YA?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IHttpResource@react@facebook@@SA?AV?$unique_ptr@UIHttpResource@react@facebook@@U?$default_delete@UIHttpResource@react@facebook@@@std@@@std@@XZ
?Make@IWebSocket@react@facebook@@SA?AV?$unique_ptr@UIWebSocket@react@facebook@@U?$default_delete@UIWebSocket@react@facebook@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@IWebSocket@React@Microsoft@@SA?AV?$unique_ptr@UIWebSocket@React@Microsoft@@U?$default_delete@UIWebSocket@React@Microsoft@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z
?Make@JSBigStringResourceDll@react@facebook@@SA?AV?$unique_ptr@$$CBVJSBigStringResourceDll@react@facebook@@U?$default_delete@$$CBVJSBigStringResourceDll@react@facebook@@@std@@@std@@PAUHINSTANCE__@@PAUHRSRC__@@@Z
YGNodeNew

Просмотреть файл

@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include <CppUnitTest.h>
#include <WebSocket.h>
using namespace boost::beast;
using namespace facebook::react;
using namespace Microsoft::React::Test;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using boost::system::error_code;
using std::make_unique;
using std::string;
TEST_CLASS(BaseWebSocketTest)
{
TEST_METHOD(CreateAndSetHandlers)
{
auto ws = make_unique<TestWebSocket>(Url("ws://validurl:0"));
Assert::IsFalse(nullptr == ws);
ws->SetOnConnect([](){});
ws->SetOnPing([](){});
ws->SetOnSend([](size_t length){});
ws->SetOnMessage([](size_t length, const string& buffer){});
ws->SetOnClose([](IWebSocket::CloseCode, const string&){});
ws->SetOnError([](const IWebSocket::Error& error){});
}
TEST_METHOD(ConnectSucceeds)
{
string errorMessage;
bool connected = false;
auto ws = make_unique<TestWebSocket>(Url("ws://localhost:80"));
ws->SetOnError([&errorMessage](IWebSocket::Error err)
{
errorMessage = err.Message;
});
ws->SetOnConnect([&connected]()
{
connected = true;
});
ws->SetConnectResult([]() -> error_code
{
return make_error_code(errc::success);
});
ws->Connect({}, {});
ws->Close(IWebSocket::CloseCode::Normal, {});
Assert::AreEqual({}, errorMessage);
Assert::IsTrue(connected);
}
TEST_METHOD(ConnectFails)
{
string errorMessage;
bool connected = false;
auto ws = make_unique<TestWebSocket>(Url("ws://localhost:80"));
ws->SetOnError([&errorMessage](IWebSocket::Error err)
{
errorMessage = err.Message;
});
ws->SetOnConnect([&connected]()
{
connected = true;
});
ws->SetConnectResult([]() -> error_code
{
return make_error_code(errc::state_not_recoverable);
});
ws->Connect({}, {});
ws->Close(IWebSocket::CloseCode::Normal, {});
Assert::AreNotEqual({}, errorMessage);
Assert::IsFalse(connected);
}
};

Просмотреть файл

@ -71,6 +71,7 @@
<ItemGroup>
<ClCompile Include="AsyncStorageManagerTest.cpp" />
<ClCompile Include="AsyncStorageTest.cpp" />
<ClCompile Include="BaseWebSocketTests.cpp" />
<ClCompile Include="BytecodeUnitTests.cpp" />
<ClCompile Include="EmptyUIManagerModule.cpp" />
<ClCompile Include="LayoutAnimationTests.cpp" />

Просмотреть файл

@ -40,6 +40,9 @@
<ClCompile Include="LayoutAnimationTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="BaseWebSocketTests.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@ -63,4 +66,4 @@
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
</Project>

Просмотреть файл

@ -6,7 +6,7 @@
#include <WebSocket.h>
using namespace boost::beast;
using namespace facebook::react;
using namespace Microsoft::React;
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using std::string;
@ -15,7 +15,7 @@ TEST_CLASS(WebSocketTest)
{
TEST_METHOD(WebSocketTest_CreateAndSetHandlers)
{
auto ws = std::make_shared<WebSocket<boost::asio::ip::tcp>>(Url("ws://validurl:0/"));
auto ws = std::make_shared<WebSocket>(Url("ws://validurl:0/"));
Assert::IsFalse(nullptr == ws);
ws->SetOnConnect([](){});
@ -30,7 +30,7 @@ TEST_CLASS(WebSocketTest)
void ConnectAndClose()
//TEST_METHOD(WebSocketTest_ConnectAndClose)
{
auto ws = std::make_shared<WebSocket<boost::asio::ip::tcp>>(Url("ws://localhost:5555/"));
auto ws = std::make_shared<WebSocket>(Url("ws://localhost:5555/"));
bool connected = false;
ws->SetOnConnect([&connected]()
{
@ -47,7 +47,7 @@ TEST_CLASS(WebSocketTest)
void SendAndReceive()
//TEST_METHOD(WebSocketTest_SendAndReceive)
{
auto ws = std::make_shared<WebSocket<boost::asio::ip::tcp>>(Url("ws://localhost:5555/"));
auto ws = std::make_shared<WebSocket>(Url("ws://localhost:5555/"));
ws->SetOnMessage([](size_t size, const string& message)
{
//EXPECT_EQ("uppercaseme_response", ss.str());//TODO: Check test server. Sending back "hello".

Просмотреть файл

@ -30,8 +30,8 @@ using std::string;
using boostecr = boost::system::error_code const&;
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
#pragma region LegacyBaseWebSocket members
@ -61,7 +61,7 @@ void LegacyBaseWebSocket<Protocol, Socket, Resolver>::Handshake(const IWebSocket
// Collect headers
for (const auto& header : options)
{
req.insert(UnicodeConversion::Utf16ToUtf8(header.first), header.second);
req.insert(facebook::react::UnicodeConversion::Utf16ToUtf8(header.first), header.second);
}
},
// Handshake handler
@ -469,6 +469,6 @@ template class LegacySecureWebSocket<tcp, ssl::stream<tcp::socket>>;
#pragma endregion // IWebSocket static members
} } // namespace facebook::react
} } // namespace Microsoft:React
#pragma warning(pop)

Просмотреть файл

@ -9,8 +9,8 @@
#include "IWebSocket.h"
#include "Utils.h"
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
template<typename Protocol, typename Socket, typename Resolver>
class LegacyBaseWebSocket : public IWebSocket
@ -89,4 +89,4 @@ public:
LegacySecureWebSocket(Url&& url);
};
} } // namespace facebook::react
} } // namespace Microsoft::React

Просмотреть файл

@ -14,7 +14,6 @@
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/asio/connect.hpp>
#include <boost/beast/core/buffers_to_string.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include "UnicodeConversion.h"
using namespace boost::archive::iterators;
@ -31,8 +30,8 @@ using std::unique_ptr;
using boostecr = boost::system::error_code const&;
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
#pragma region BaseWebSocket members
@ -64,7 +63,7 @@ void BaseWebSocket<Protocol, Socket, Resolver>::Handshake(const IWebSocket::Opti
// Collect headers
for (const auto& header : options)
{
req.insert(UnicodeConversion::Utf16ToUtf8(header.first), header.second);
req.insert(facebook::react::UnicodeConversion::Utf16ToUtf8(header.first), header.second);
}
},
// Handshake handler
@ -445,32 +444,26 @@ IWebSocket::ReadyState BaseWebSocket<Protocol, Socket, Resolver>::GetReadyState(
#pragma region WebSocket members
template<typename Protocol, typename Socket, typename Resolver>
WebSocket<Protocol, Socket, Resolver>::WebSocket(Url&& url)
: BaseWebSocket<Protocol, Socket, Resolver>(std::move(url))
WebSocket::WebSocket(Url&& url)
: BaseWebSocket(std::move(url))
{
this->m_stream = make_unique<websocket::stream<Socket>>(this->m_context);
this->m_stream = make_unique<websocket::stream<basic_stream_socket<tcp>>>(this->m_context);
this->m_stream->auto_fragment(false);//ISS:2906963 Re-enable message fragmenting.
}
// Define the default implementation.
template class WebSocket<boost::asio::ip::tcp>;
#pragma endregion
#pragma region SecureWebSocket members
template<typename Protocol, typename Socket, typename Resolver>
SecureWebSocket<Protocol, Socket, Resolver>::SecureWebSocket(Url&& url)
: BaseWebSocket<Protocol, Socket, Resolver>(std::move(url))
SecureWebSocket::SecureWebSocket(Url&& url)
: BaseWebSocket(std::move(url))
{
auto ssl = ssl::context(ssl::context::sslv23_client);
this->m_stream = make_unique<websocket::stream<Socket>>(this->m_context, ssl);
this->m_stream = make_unique<websocket::stream<ssl::stream<tcp::socket>>>(this->m_context, ssl);
this->m_stream->auto_fragment(false);//ISS:2906963 Re-enable message fragmenting.
}
template<typename Protocol, typename Socket, typename Resolver>
void SecureWebSocket<Protocol, Socket, Resolver>::Handshake(const IWebSocket::Options& options)
void SecureWebSocket::Handshake(const IWebSocket::Options& options)
{
this->m_stream->next_layer().async_handshake(ssl::stream_base::client, [this, options = std::move(options)](boostecr ec)
{
@ -480,13 +473,11 @@ void SecureWebSocket<Protocol, Socket, Resolver>::Handshake(const IWebSocket::Op
}
else
{
BaseWebSocket<Protocol, Socket, Resolver>::Handshake(std::move(options));
BaseWebSocket::Handshake(std::move(options));
}
});
}
template class SecureWebSocket<tcp, ssl::stream<tcp::socket>>;
#pragma endregion // SecureWebSocket members
#pragma region IWebSocket static members
@ -500,14 +491,14 @@ template class SecureWebSocket<tcp, ssl::stream<tcp::socket>>;
if (url.port.empty())
url.port = "80";
return unique_ptr<IWebSocket>(new WebSocket<tcp>(std::move(url)));
return unique_ptr<IWebSocket>(new WebSocket(std::move(url)));
}
else if (url.scheme == "wss")
{
if (url.port.empty())
url.port = "443";
return unique_ptr<IWebSocket>(new SecureWebSocket<tcp, ssl::stream<tcp::socket>>(std::move(url)));
return unique_ptr<IWebSocket>(new SecureWebSocket(std::move(url)));
}
else
throw std::exception((string("Incorrect url protocol: ") + url.scheme).c_str());
@ -517,4 +508,196 @@ template class SecureWebSocket<tcp, ssl::stream<tcp::socket>>;
} } // namespace facebook::react
namespace Microsoft {
namespace React {
namespace Test {
#pragma region MockStream
MockStream::MockStream(io_context& context)
: m_context{ context }
{
}
io_context::executor_type MockStream::get_executor() noexcept
{
return m_context.get_executor();
}
MockStream::lowest_layer_type& MockStream::lowest_layer()
{
return *this;
}
MockStream::lowest_layer_type const& MockStream::lowest_layer() const
{
return *this;
}
void MockStream::binary(bool value) {}
bool MockStream::got_binary() const
{
return false;
}
bool MockStream::got_text() const
{
return !got_binary();
}
void MockStream::auto_fragment(bool value) {}
bool MockStream::auto_fragment() const
{
return false;
}
void MockStream::write_buffer_size(size_t amount) {}
size_t MockStream::write_buffer_size() const
{
return 8;
}
#pragma region boost::beast::websocket::stream NextLayer methods
template<class DynamicBuffer, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(error_code, size_t))
MockStream::async_read(DynamicBuffer& buffer, ReadHandler&& handler)
{
//TODO: Mock
}
template<class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(error_code, size_t))
MockStream::async_write(ConstBufferSequence const& buffers, WriteHandler&& handler)
{
//TODO: Mock
}
template<class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(error_code))
MockStream::async_ping(websocket::ping_data const& payload, WriteHandler&& handler)
{
//TODO: Mock
}
template<class CloseHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(CloseHandler, void(error_code))
MockStream::async_close(websocket::close_reason const& cr, CloseHandler&& handler)
{
//TODO: Mock
}
// AsyncStream compliance
template<class MutableBufferSequence, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(error_code, size_t))
MockStream::async_read_some(MutableBufferSequence const& buffers, ReadHandler&& handler)
{
//TODO: Mock
}
template<class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(error_code, size_t))
MockStream::async_write_some(ConstBufferSequence const& buffers, WriteHandler&& handler)
{
//TODO: Mock
}
#pragma endregion // boost::beast::websocket::stream NextLayer methods
#pragma endregion // MockStream
#pragma region TestWebSocket
TestWebSocket::TestWebSocket(facebook::react::Url&& url)
: BaseWebSocket(std::move(url))
{
m_stream = make_unique<websocket::stream<MockStream>>(m_context);
m_stream->auto_fragment(false);//ISS:2906963 Re-enable message fragmenting.
}
void TestWebSocket::SetConnectResult(std::function<error_code()>&& resultFunc)
{
m_stream->next_layer().ConnectResult = std::move(resultFunc);
}
#pragma endregion
} } } // namespace Microsoft::React::Test
namespace boost {
namespace asio {
// See <boost/asio/connect.hpp>(776)
template
<
typename Iterator,
typename IteratorConnectHandler
>
BOOST_ASIO_INITFN_RESULT_TYPE(IteratorConnectHandler, void(boost::system::error_code, Iterator))
async_connect
(
Microsoft::React::Test::MockStream& s,
Iterator begin,
Iterator end,
BOOST_ASIO_MOVE_ARG(IteratorConnectHandler) handler
)
{
handler(s.ConnectResult(), {});
}
} // namespace boost::asio
// HTTP low-level mock overrides.
namespace beast {
namespace http {
///
// msg - type http::message<0, http::basic_string_body<char, std::char_traits<char>, std::allocator<char>>, http::basic_fields<std::allocator<char>>>
///
template<class DynamicBuffer, bool isRequest, class Body, class Allocator, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(error_code, std::size_t))
async_read(Microsoft::React::Test::MockStream& stream, DynamicBuffer& buffer, message<isRequest, Body, basic_fields<Allocator>>& msg, ReadHandler&& handler)
{
// Build response.
// TODO: Make mockable?
msg.result(status::switching_protocols);
msg.version(11);
msg.set(field::upgrade, "websocket");
msg.set(field::connection, "upgrade");
msg.set(field::sec_websocket_key, stream.Key); //TODO: Keep this, or accepted key (acc)?
msg.set(field::sec_websocket_version, "13");
msg.set(field::user_agent, BOOST_BEAST_VERSION_STRING);
websocket::detail::sec_ws_accept_type acc;
websocket::detail::make_sec_ws_accept(acc, stream.Key);
msg.set(field::sec_websocket_accept, acc);
BOOST_BEAST_HANDLER_INIT(ReadHandler, void(error_code, std::size_t));
boost::asio::post(stream.get_executor(), bind_handler(std::move(init.completion_handler), boost::system::error_code{}, 0));
return init.result.get();
}
///
// sr - type http::serializer<1, http::empty_body, http::basic_fields<std::allocator<char>>>
///
template<bool isRequest, class Body, class Fields, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(error_code, std::size_t))
async_write(Microsoft::React::Test::MockStream& stream, serializer<isRequest, Body, Fields>& sr, WriteHandler&& handler)
{
stream.Key = sr.get().at(field::sec_websocket_key);
BOOST_BEAST_HANDLER_INIT(WriteHandler, void(error_code, std::size_t));
boost::asio::post(stream.get_executor(), bind_handler(std::move(init.completion_handler), boost::system::error_code{}, 0));
return init.result.get();
}
} } // namespace boost::beast::http
} // namespace boost
#pragma warning(pop)

Просмотреть файл

@ -4,13 +4,14 @@
#pragma once
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <thread>
#include <queue>
#include "IWebSocket.h"
#include "Utils.h"
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
template<typename Protocol, typename Socket, typename Resolver>
class BaseWebSocket : public IWebSocket
@ -89,15 +90,25 @@ public:
#pragma endregion
};
template<typename Protocol, typename Socket = boost::asio::basic_stream_socket<Protocol>, typename Resolver = boost::asio::ip::basic_resolver<Protocol>>
class WebSocket : public BaseWebSocket<Protocol, Socket, Resolver>
class WebSocket
: public BaseWebSocket
<
boost::asio::ip::tcp,
boost::asio::basic_stream_socket<boost::asio::ip::tcp>,
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>
>
{
public:
WebSocket(Url&& url);
};
template<typename Protocol, typename Socket, typename Resolver = boost::asio::ip::basic_resolver<Protocol>>
class SecureWebSocket : public BaseWebSocket<Protocol, Socket, Resolver>
class SecureWebSocket
: public BaseWebSocket
<
boost::asio::ip::tcp,
boost::asio::ssl::stream<boost::asio::ip::tcp::socket>,
boost::asio::ip::basic_resolver<boost::asio::ip::tcp>
>
{
#pragma region BaseWebSocket overrides
@ -109,4 +120,99 @@ public:
SecureWebSocket(Url&& url);
};
} } // namespace facebook::react
namespace Test {
// See <boost/beast/experimental/test/stream.hpp>
class MockStream
{
friend void teardown
(
boost::beast::websocket::role_type,
MockStream&,
boost::system::error_code&
) {}
template<class TeardownHandler>
friend void async_teardown
(
boost::beast::websocket::role_type,
MockStream&,
TeardownHandler&&
) {}
boost::asio::io_context& m_context;
public:
MockStream(boost::asio::io_context& context);
std::function<boost::system::error_code()> ConnectResult;
boost::beast::websocket::detail::sec_ws_key_type Key;
using is_deflate_supported = std::integral_constant<bool, false>;
using next_layer_type = MockStream;
using lowest_layer_type = MockStream;
using executor_type = boost::asio::io_context::executor_type;
using lowest_layer_type = MockStream;
lowest_layer_type& lowest_layer();
lowest_layer_type const& lowest_layer() const;
void binary(bool value);
bool got_binary() const;
bool got_text() const;
void auto_fragment(bool value);
bool auto_fragment() const;
void write_buffer_size(std::size_t amount);
std::size_t write_buffer_size() const;
template<class DynamicBuffer, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(boost::system::error_code, std::size_t))
async_read(DynamicBuffer& buffer, ReadHandler&& handler);
template<class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(boost::system::error_code, std::size_t))
async_write(ConstBufferSequence const& buffers, WriteHandler&& handler);
template<class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(boost::system::error_code))
async_ping(boost::beast::websocket::ping_data const& payload, WriteHandler&& handler);
template<class CloseHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(CloseHandler, void(boost::system::error_code))
async_close(boost::beast::websocket::close_reason const& cr, CloseHandler&& handler);
// AsyncStream compliance
template<class MutableBufferSequence, class ReadHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void(boost::system::error_code, std::size_t))
async_read_some(MutableBufferSequence const& buffers, ReadHandler&& handler);
template<class ConstBufferSequence, class WriteHandler>
BOOST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void(boost::system::error_code, std::size_t))
async_write_some(ConstBufferSequence const& buffers, WriteHandler&& handler);
boost::asio::io_context::executor_type get_executor() noexcept;
};
class TestWebSocket : public BaseWebSocket<boost::asio::ip::tcp, MockStream, boost::asio::ip::basic_resolver<boost::asio::ip::tcp>>
{
public:
TestWebSocket(facebook::react::Url&& url);
void SetConnectResult(std::function<boost::system::error_code()>&& resultFunc);
};
} // namespace Microsoft::React::Test
} } // namespace Microsoft::React

Просмотреть файл

@ -15,7 +15,8 @@ using namespace folly;
using std::string;
namespace facebook { namespace react {
namespace Microsoft {
namespace React {
WebSocketModule::WebSocketModule()
{
@ -54,7 +55,7 @@ std::vector<facebook::xplat::module::CxxModule::Method> WebSocketModule::getMeth
dynamic headersDynamic = optionsDynamic["headers"];
for (const auto& header : headersDynamic.items())
{
options.emplace(UnicodeConversion::Utf8ToUtf16(header.first.getString()), header.second.getString());
options.emplace(facebook::react::UnicodeConversion::Utf8ToUtf16(header.first.getString()), header.second.getString());
}
}
@ -142,4 +143,4 @@ std::unique_ptr<facebook::xplat::module::CxxModule> CreateWebSocketModule() noex
return std::make_unique<WebSocketModule>();
}
} } // facebook::react
} } // Microsoft::React

Просмотреть файл

@ -125,12 +125,12 @@ Global
Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Debug|ARM = Debug|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
Release|ARM = Release|ARM
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8B88FFAE-4DBC-49A2-AFA5-D2477D4AD189}.Debug|ARM.ActiveCfg = Debug|ARM

Просмотреть файл

@ -7,8 +7,8 @@
#include <map>
#include <vector>
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
struct IWebSocket
{
@ -103,3 +103,11 @@ struct IWebSocket
};
} } // namespace facebook::react
// Deprecated. Keeping for compatibility with dependent code.
namespace facebook {
namespace react {
using IWebSocket = Microsoft::React::IWebSocket;
} } // namespace facebook::react

Просмотреть файл

@ -6,7 +6,8 @@
using namespace std;
namespace facebook { namespace react {
namespace Microsoft {
namespace React {
Url::Url(const string& source)
{
@ -50,7 +51,7 @@ string Url::Target()
return path.append("?").append(queryString);
}
}} // namespace facebook::react
} } // namespace Microsoft::React
// Folly/folly/SafeAssert.cpp brings in a bunch of file APIs that we otherwise dont need
// And we probably want to look at some other functionality for reporting errors at
@ -80,4 +81,5 @@ void assertionFailure(
}
} // namespace detail
} // namespace folly
} // namespace folly

Просмотреть файл

@ -5,7 +5,8 @@
#include <string>
namespace facebook { namespace react {
namespace Microsoft {
namespace React {
struct Url
{
@ -20,4 +21,12 @@ struct Url
std::string Target();
};
}} // namespace facebook::react
} } // namespace Microsoft::React
// Deprecated. Keeping for compatibility.
namespace facebook {
namespace react {
using Url = Microsoft::React::Url;
} } // namespace facebook::react

Просмотреть файл

@ -6,8 +6,8 @@
#include <cxxreact/CxxModule.h>
#include "IWebSocket.h"
namespace facebook {
namespace react {
namespace Microsoft {
namespace React {
class WebSocketModule : public facebook::xplat::module::CxxModule
{
@ -34,4 +34,12 @@ private:
std::map<int64_t, std::unique_ptr<IWebSocket>> m_webSockets;
};
} } // facebook::react
} } // Microsoft::React
// Deprecated. Keeping for compatibility.
namespace facebook {
namespace react {
using WebSocketModule = Microsoft::React::WebSocketModule;
} } // namespace facebook::react