Skip to content

Commit 8b08788

Browse files
willromanBrennanConroy
authored andcommitted
Willroman/create json (#23)
* Modifications to createJson() in json_helpers to handle differently sized signed and unsigned integer values.
1 parent f771631 commit 8b08788

File tree

2 files changed

+163
-1
lines changed

2 files changed

+163
-1
lines changed

src/signalrclient/json_helpers.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "stdafx.h"
55
#include "json_helpers.h"
66
#include <cmath>
7+
#include <stdint.h>
78

89
namespace signalr
910
{
@@ -57,7 +58,32 @@ namespace signalr
5758
// because the server expects certain values to be 1 instead of 1.0 (like protocol version)
5859
if (std::modf(value, &intPart) == 0)
5960
{
60-
return Json::Value((int)intPart);
61+
if (value < 0)
62+
{
63+
if (value >= (double)INT64_MIN)
64+
{
65+
// Fits within int64_t
66+
return Json::Value(static_cast<int64_t>(intPart));
67+
}
68+
else
69+
{
70+
// Remain as double
71+
return Json::Value(value);
72+
}
73+
}
74+
else
75+
{
76+
if (value <= (double)UINT64_MAX)
77+
{
78+
// Fits within uint64_t
79+
return Json::Value(static_cast<uint64_t>(intPart));
80+
}
81+
else
82+
{
83+
// Remain as double
84+
return Json::Value(value);
85+
}
86+
}
6187
}
6288
return Json::Value(v.as_double());
6389
}

test/signalrclienttests/hub_connection_tests.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,77 @@ hub_connection create_hub_connection(std::shared_ptr<websocket_client> websocket
2222
.build();
2323
}
2424

25+
template<typename TValue>
26+
std::string build_websocket_message_string(TValue value)
27+
{
28+
std::ostringstream stream;
29+
stream << "{ \"type\": 3, \"invocationId\": \"0\", \"result\": [" << value << "] }\x1e";
30+
31+
return stream.str();
32+
}
33+
34+
template<int32_t precision>
35+
std::string format_double_as_string(double value)
36+
{
37+
std::ostringstream stream;
38+
stream << std::setprecision(precision) << value;
39+
40+
return stream.str();
41+
}
42+
43+
template<typename TValue>
44+
void invoke_common_numeric_handling_logic(TValue original_value, std::function<void(TValue, TValue)> assertion_callback)
45+
{
46+
std::string websocket_message = build_websocket_message_string(original_value);
47+
48+
auto websocket_client = create_test_websocket_client();
49+
auto hub_connection = create_hub_connection(websocket_client);
50+
51+
auto connect_mre = manual_reset_event<void>();
52+
53+
hub_connection.start([&connect_mre](std::exception_ptr exception)
54+
{
55+
connect_mre.set(exception);
56+
});
57+
58+
ASSERT_FALSE(websocket_client->receive_loop_started.wait(5000));
59+
ASSERT_FALSE(websocket_client->handshake_sent.wait(5000));
60+
61+
websocket_client->receive_message("{ }\x1e");
62+
63+
connect_mre.get();
64+
65+
auto callback_mre = manual_reset_event<signalr::value>();
66+
67+
std::vector<signalr::value> arr{ signalr::value((double)original_value) };
68+
69+
hub_connection.invoke("method", signalr::value(arr), [&callback_mre](const signalr::value& message, std::exception_ptr exception)
70+
{
71+
if (exception)
72+
{
73+
callback_mre.set(exception);
74+
}
75+
else
76+
{
77+
callback_mre.set(message);
78+
}
79+
});
80+
81+
websocket_client->receive_message(websocket_message);
82+
83+
auto result = callback_mre.get();
84+
85+
ASSERT_TRUE(result.is_array());
86+
87+
auto array = result.as_array();
88+
89+
ASSERT_EQ(1, array.size());
90+
91+
auto value = static_cast<TValue>(array[0].as_double());
92+
93+
assertion_callback(value, original_value);
94+
}
95+
2596
TEST(url, negotiate_appended_to_url)
2697
{
2798
std::string base_urls[] = { "http://fakeuri", "http://fakeuri/" };
@@ -1168,3 +1239,68 @@ TEST(invoke, send_throws_when_the_underlying_connection_is_not_valid)
11681239
ASSERT_STREQ("cannot send data when the connection is not in the connected state. current connection state: disconnected", e.what());
11691240
}
11701241
}
1242+
1243+
TEST(invoke, invoke_handles_UINT32_MAX_value_as_unsigned_int)
1244+
{
1245+
invoke_common_numeric_handling_logic<unsigned int>(UINT32_MAX, [](unsigned int result, unsigned int expected)
1246+
{
1247+
ASSERT_EQ(result, expected);
1248+
});
1249+
}
1250+
1251+
TEST(invoke, invoke_handles_INT64_MIN_value_as_int64_t)
1252+
{
1253+
invoke_common_numeric_handling_logic<long long>(INT64_MIN, [](long long result, long long expected)
1254+
{
1255+
ASSERT_EQ(result, expected);
1256+
});
1257+
}
1258+
1259+
TEST(invoke, invoke_handles_INT64_MIN_minus_1_value_as_double)
1260+
{
1261+
invoke_common_numeric_handling_logic<double>((INT64_MIN - 1.0), [](double result, double expected)
1262+
{
1263+
std::string result_string = format_double_as_string<6>(result);
1264+
std::string expected_string = format_double_as_string<6>(expected);
1265+
1266+
ASSERT_EQ(result_string, expected_string);
1267+
});
1268+
}
1269+
1270+
TEST(invoke, invoke_handles_UINT64_MAX_value_as_uint64_t)
1271+
{
1272+
invoke_common_numeric_handling_logic<long long>(UINT64_MAX, [](long long result, long long expected)
1273+
{
1274+
ASSERT_EQ(result, expected);
1275+
});
1276+
}
1277+
1278+
TEST(invoke, invoke_handles_UINT64_MAX_plus_1_value_as_double)
1279+
{
1280+
invoke_common_numeric_handling_logic<double>((UINT64_MAX + 1.0), [](double result, double expected)
1281+
{
1282+
std::string result_string = format_double_as_string<6>(result);
1283+
std::string expected_string = format_double_as_string<6>(expected);
1284+
1285+
ASSERT_EQ(result_string, expected_string);
1286+
});
1287+
}
1288+
1289+
TEST(invoke, invoke_handles_non_integer_value_as_double)
1290+
{
1291+
invoke_common_numeric_handling_logic<double>(3.1415926, [](double result, double expected)
1292+
{
1293+
std::string result_string = format_double_as_string<6>(result);
1294+
std::string expected_string = format_double_as_string<6>(expected);
1295+
1296+
ASSERT_EQ(result_string, expected_string);
1297+
});
1298+
}
1299+
1300+
TEST(invoke, invoke_handles_zero_value_as_int)
1301+
{
1302+
invoke_common_numeric_handling_logic<int>(0, [](int result, int expected)
1303+
{
1304+
ASSERT_EQ(result, expected);
1305+
});
1306+
}

0 commit comments

Comments
 (0)