Remaining SonarCloud Bugs (#6900)
* (WIP)-all issues corrected, tests started * first test passing alternative solution for SonarCloud check fixed for to while translation added changelog item adding tests and fixes more tests; avoid compiling BSD Tests on Windows attempting a BSD compile patch more tests borrowing symbol detection from another test more ambitious testing changed the order of assertions for better info more tests fixed clear errors before executing expanding transformation to use string comparison including terminator on translation count a different flag for testing MS Windows differente Windows flag more tests fixing platform encoding match Windows compiler difference on #ifdef Google Test macro usage fix test added added keymap test test and initialisation fixed ms cl issue with named init test for keymap exercising keystate more configuration exercises one more test for config added Unicode test an IPv6 test more portable networking code using our own platform switching code avoiding strcpy * Fixed typo in Changelog. * +appropriate memory handling * one more test for coverage * a tad more coverage * expanded test on Config Co-authored-by: Max <maxmommersteeg@hotmail.com> Co-authored-by: SerhiiGadzhilov <71632867+SerhiiGadzhilov@users.noreply.github.com>
This commit is contained in:
parent
c06cdda15f
commit
5c2311a50a
23 changed files with 582 additions and 110 deletions
|
|
@ -1,5 +1,7 @@
|
|||
v1.13.1-snapshot
|
||||
===========
|
||||
Bug fixes:
|
||||
- #6900 Remaining SonarCloud reported bug items
|
||||
- #6889 Systray Icon on Ubuntu Auto Start (take 2)
|
||||
===========
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ IArchString::convStringWCToMB(char* dst,
|
|||
if (errors == NULL) {
|
||||
errors = &dummyErrors;
|
||||
}
|
||||
*errors = false;
|
||||
|
||||
if (s_mutex == NULL) {
|
||||
s_mutex = ARCH->newMutex();
|
||||
|
|
@ -57,13 +58,15 @@ IArchString::convStringWCToMB(char* dst,
|
|||
|
||||
if (dst == NULL) {
|
||||
char dummy[MB_LEN_MAX];
|
||||
for (const wchar_t* scan = src; n > 0; ++scan, --n) {
|
||||
const wchar_t* scan = src;
|
||||
for (; n > 0; --n) {
|
||||
ptrdiff_t mblen = wctomb(dummy, *scan);
|
||||
if (mblen == -1) {
|
||||
*errors = true;
|
||||
mblen = 1;
|
||||
}
|
||||
len += mblen;
|
||||
++scan;
|
||||
}
|
||||
ptrdiff_t mblen = wctomb(dummy, L'\0');
|
||||
if (mblen != -1) {
|
||||
|
|
@ -72,7 +75,8 @@ IArchString::convStringWCToMB(char* dst,
|
|||
}
|
||||
else {
|
||||
char* dst0 = dst;
|
||||
for (const wchar_t* scan = src; n > 0; ++scan, --n) {
|
||||
const wchar_t* scan = src;
|
||||
for (; n > 0; --n) {
|
||||
ptrdiff_t mblen = wctomb(dst, *scan);
|
||||
if (mblen == -1) {
|
||||
*errors = true;
|
||||
|
|
@ -81,6 +85,7 @@ IArchString::convStringWCToMB(char* dst,
|
|||
else {
|
||||
dst += mblen;
|
||||
}
|
||||
++scan;
|
||||
}
|
||||
ptrdiff_t mblen = wctomb(dst, L'\0');
|
||||
if (mblen != -1) {
|
||||
|
|
@ -105,6 +110,7 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
|||
if (errors == NULL) {
|
||||
errors = &dummyErrors;
|
||||
}
|
||||
*errors = false;
|
||||
|
||||
if (s_mutex == NULL) {
|
||||
s_mutex = ARCH->newMutex();
|
||||
|
|
@ -113,7 +119,8 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
|||
ARCH->lockMutex(s_mutex);
|
||||
|
||||
if (dst == NULL) {
|
||||
for (const char* scan = src; n > 0; ) {
|
||||
const char* scan = src;
|
||||
while (n > 0) {
|
||||
ptrdiff_t mblen = mbtowc(&dummy, scan, n);
|
||||
switch (mblen) {
|
||||
case -2:
|
||||
|
|
@ -149,7 +156,8 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
|||
}
|
||||
else {
|
||||
wchar_t* dst0 = dst;
|
||||
for (const char* scan = src; n > 0; ++dst) {
|
||||
const char* scan = src;
|
||||
while (n > 0) {
|
||||
ptrdiff_t mblen = mbtowc(dst, scan, n);
|
||||
switch (mblen) {
|
||||
case -2:
|
||||
|
|
@ -180,6 +188,7 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
|||
n -= static_cast<int>(mblen);
|
||||
break;
|
||||
}
|
||||
++dst;
|
||||
}
|
||||
len = dst - dst0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,8 +45,9 @@ public:
|
|||
enum EWideCharEncoding {
|
||||
kUCS2, //!< The UCS-2 encoding
|
||||
kUCS4, //!< The UCS-4 encoding
|
||||
kUTF16, //!< The UTF-16 encoding
|
||||
kUTF32 //!< The UTF-32 encoding
|
||||
kUTF16, //!< The UTF-16 encoding
|
||||
kUTF32, //!< The UTF-32 encoding
|
||||
kPlatformDetermined
|
||||
};
|
||||
|
||||
//! @name manipulators
|
||||
|
|
|
|||
|
|
@ -35,17 +35,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <cstring>
|
||||
|
||||
#if HAVE_POLL
|
||||
# include <poll.h>
|
||||
#else
|
||||
# if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_INET_ATON
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
|
@ -87,12 +76,14 @@ inet_aton(const char* cp, struct in_addr* inp)
|
|||
// ArchNetworkBSD
|
||||
//
|
||||
|
||||
ArchNetworkBSD::Connectors ArchNetworkBSD::s_connectors;
|
||||
|
||||
ArchNetworkBSD::ArchNetworkBSD()
|
||||
= default;
|
||||
|
||||
ArchNetworkBSD::~ArchNetworkBSD()
|
||||
{
|
||||
ARCH->closeMutex(m_mutex);
|
||||
if (m_mutex) ARCH->closeMutex(m_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -321,7 +312,7 @@ ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout)
|
|||
int t = (timeout < 0.0) ? -1 : static_cast<int>(1000.0 * timeout);
|
||||
|
||||
// do the poll
|
||||
n = poll(pfd, n, t);
|
||||
n = s_connectors.poll_impl(pfd, n, t);
|
||||
|
||||
// reset the unblock pipe
|
||||
if (n > 0 && unblockPipe != nullptr && (pfd[num].revents & POLLIN) != 0) {
|
||||
|
|
@ -347,6 +338,7 @@ ArchNetworkBSD::pollSocket(PollEntry pe[], int num, double timeout)
|
|||
}
|
||||
delete[] pfd;
|
||||
throwError(errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// translate back
|
||||
|
|
@ -849,8 +841,8 @@ ArchNetworkBSD::isAnyAddr(ArchNetAddress addr)
|
|||
|
||||
case kINET6: {
|
||||
struct sockaddr_in6* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
|
||||
return (memcmp(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any)) == 0 &&
|
||||
addr->m_len == (socklen_t)sizeof(struct sockaddr_in6));
|
||||
return (addr->m_len == (socklen_t)sizeof(struct sockaddr_in6) &&
|
||||
memcmp(static_cast<const void*>(&ipAddr->sin6_addr), static_cast<const void*>(&in6addr_any), sizeof(in6_addr)) == 0);
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -26,12 +26,31 @@
|
|||
#endif
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#else
|
||||
struct sockaddr_storage {
|
||||
unsigned char ss_len; /* address length */
|
||||
unsigned char ss_family; /* [XSI] address family */
|
||||
char __ss_pad1[_SS_PAD1SIZE];
|
||||
long long __ss_align; /* force structure storage alignment */
|
||||
char __ss_pad2[_SS_PAD2SIZE];
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !HAVE_SOCKLEN_T
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#if HAVE_POLL
|
||||
# include <poll.h>
|
||||
#else
|
||||
# if HAVE_SYS_SELECT_H
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// old systems may use char* for [gs]etsockopt()'s optval argument.
|
||||
// this should be void on modern systems but char is forwards
|
||||
// compatible so we always use it.
|
||||
|
|
@ -99,6 +118,19 @@ public:
|
|||
virtual bool isAnyAddr(ArchNetAddress);
|
||||
virtual bool isEqualAddr(ArchNetAddress, ArchNetAddress);
|
||||
|
||||
struct Connectors
|
||||
{
|
||||
#if HAVE_POLL
|
||||
int (*poll_impl)(struct pollfd *, nfds_t, int);
|
||||
#endif // HAVE_POLL
|
||||
Connectors() {
|
||||
#if HAVE_POLL
|
||||
poll_impl = poll;
|
||||
#endif // HAVE_POLL
|
||||
}
|
||||
};
|
||||
static Connectors s_connectors;
|
||||
|
||||
private:
|
||||
const int* getUnblockPipe();
|
||||
const int* getUnblockPipeForThread(ArchThread);
|
||||
|
|
@ -107,5 +139,5 @@ private:
|
|||
void throwNameError(int);
|
||||
|
||||
private:
|
||||
ArchMutex m_mutex;
|
||||
ArchMutex m_mutex {};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ vformat(const char* fmt, va_list args)
|
|||
std::vector<size_t> width;
|
||||
std::vector<size_t> index;
|
||||
size_t maxIndex = 0;
|
||||
for (const char* scan = fmt; *scan != '\0'; ++scan) {
|
||||
const char* scan = fmt;
|
||||
while ( *scan ) {
|
||||
if (*scan == '%') {
|
||||
++scan;
|
||||
if (*scan == '\0') {
|
||||
|
|
@ -88,6 +89,7 @@ vformat(const char* fmt, va_list args)
|
|||
// improper escape -- ignore
|
||||
}
|
||||
}
|
||||
++scan;
|
||||
}
|
||||
|
||||
// get args
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ Unicode::UTF32ToUTF8(const String& src, bool* errors)
|
|||
}
|
||||
|
||||
String
|
||||
Unicode::textToUTF8(const String& src, bool* errors)
|
||||
Unicode::textToUTF8(const String& src, bool* errors, IArchString::EWideCharEncoding encoding)
|
||||
{
|
||||
// default to success
|
||||
resetError(errors);
|
||||
|
|
@ -309,7 +309,7 @@ Unicode::textToUTF8(const String& src, bool* errors)
|
|||
ARCH->convStringMBToWC(wcs, src.c_str(), n, errors);
|
||||
|
||||
// convert to UTF8
|
||||
String utf8 = wideCharToUTF8(wcs, len, errors);
|
||||
String utf8 = wideCharToUTF8(wcs, len, errors, encoding);
|
||||
|
||||
// clean up
|
||||
delete[] wcs;
|
||||
|
|
@ -354,12 +354,15 @@ Unicode::UTF8ToWideChar(const String& src, UInt32& size, bool* errors)
|
|||
}
|
||||
|
||||
String
|
||||
Unicode::wideCharToUTF8(const wchar_t* src, UInt32 size, bool* errors)
|
||||
Unicode::wideCharToUTF8(const wchar_t* src, UInt32 size, bool* errors, IArchString::EWideCharEncoding encoding)
|
||||
{
|
||||
if (encoding == IArchString::kPlatformDetermined) {
|
||||
encoding = ARCH->getWideCharEncoding();
|
||||
}
|
||||
// convert from platform's wide character encoding.
|
||||
// note -- this must include a wide nul character (independent of
|
||||
// the String's nul character).
|
||||
switch (ARCH->getWideCharEncoding()) {
|
||||
switch (encoding) {
|
||||
case IArchString::kUCS2:
|
||||
return doUCS2ToUTF8(reinterpret_cast<const UInt8*>(src), size, errors);
|
||||
|
||||
|
|
@ -406,9 +409,10 @@ Unicode::doUCS2ToUTF8(const UInt8* data, UInt32 n, bool* errors)
|
|||
}
|
||||
|
||||
// convert each character
|
||||
for (; n > 0; data += 2, --n) {
|
||||
for (; n > 0; --n) {
|
||||
UInt32 c = decode16(data, byteSwapped);
|
||||
toUTF8(dst, c, errors);
|
||||
data += 2;
|
||||
}
|
||||
|
||||
return dst;
|
||||
|
|
@ -442,9 +446,10 @@ Unicode::doUCS4ToUTF8(const UInt8* data, UInt32 n, bool* errors)
|
|||
}
|
||||
|
||||
// convert each character
|
||||
for (; n > 0; data += 4, --n) {
|
||||
for (; n > 0; --n) {
|
||||
UInt32 c = decode32(data, byteSwapped);
|
||||
toUTF8(dst, c, errors);
|
||||
data += 4;
|
||||
}
|
||||
|
||||
return dst;
|
||||
|
|
@ -478,7 +483,7 @@ Unicode::doUTF16ToUTF8(const UInt8* data, UInt32 n, bool* errors)
|
|||
}
|
||||
|
||||
// convert each character
|
||||
for (; n > 0; data += 2, --n) {
|
||||
while (n > 0) {
|
||||
UInt32 c = decode16(data, byteSwapped);
|
||||
if (c < 0x0000d800 || c > 0x0000dfff) {
|
||||
toUTF8(dst, c, errors);
|
||||
|
|
@ -507,6 +512,8 @@ Unicode::doUTF16ToUTF8(const UInt8* data, UInt32 n, bool* errors)
|
|||
setError(errors);
|
||||
toUTF8(dst, s_replacement, NULL);
|
||||
}
|
||||
data += 2;
|
||||
--n;
|
||||
}
|
||||
|
||||
return dst;
|
||||
|
|
@ -540,13 +547,14 @@ Unicode::doUTF32ToUTF8(const UInt8* data, UInt32 n, bool* errors)
|
|||
}
|
||||
|
||||
// convert each character
|
||||
for (; n > 0; data += 4, --n) {
|
||||
for (; n > 0; --n) {
|
||||
UInt32 c = decode32(data, byteSwapped);
|
||||
if (c >= 0x00110000) {
|
||||
setError(errors);
|
||||
c = s_replacement;
|
||||
}
|
||||
toUTF8(dst, c, errors);
|
||||
data += 4;
|
||||
}
|
||||
|
||||
return dst;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "base/String.h"
|
||||
#include "arch/IArchString.h"
|
||||
#include "common/basic_types.h"
|
||||
|
||||
//! Unicode utility functions
|
||||
|
|
@ -111,7 +112,7 @@ public:
|
|||
Convert from the current locale encoding to UTF-8. If errors is not
|
||||
NULL then *errors is set to true iff any character could not be decoded.
|
||||
*/
|
||||
static String textToUTF8(const String&, bool* errors = NULL);
|
||||
static String textToUTF8(const String&, bool* errors = nullptr, IArchString::EWideCharEncoding encoding = IArchString::kPlatformDetermined);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
@ -126,7 +127,8 @@ private:
|
|||
// convert nul terminated wchar_t string (in platform's native
|
||||
// encoding) to UTF8.
|
||||
static String wideCharToUTF8(const wchar_t*,
|
||||
UInt32 size, bool* errors);
|
||||
UInt32 size, bool* errors,
|
||||
IArchString::EWideCharEncoding encoding = IArchString::kPlatformDetermined);
|
||||
|
||||
// internal conversion to UTF8
|
||||
static String doUCS2ToUTF8(const UInt8* src, UInt32 n, bool* errors);
|
||||
|
|
|
|||
|
|
@ -171,7 +171,7 @@ NetworkAddress::resolve()
|
|||
bool
|
||||
NetworkAddress::operator==(const NetworkAddress& addr) const
|
||||
{
|
||||
return ARCH->isEqualAddr(m_address, addr.m_address);
|
||||
return m_address == addr.m_address || ARCH->isEqualAddr(m_address, addr.m_address);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -1110,7 +1110,8 @@ XWindowsClipboard::sendReply(Reply* reply)
|
|||
// if there are any non-ascii characters in string
|
||||
// then print the binary data.
|
||||
static const char* hex = "0123456789abcdef";
|
||||
for (String::size_type j = 0; j < data.size(); ++j) {
|
||||
String::size_type j = 0;
|
||||
while (j < data.size()) {
|
||||
if (data[j] < 32 || data[j] > 126) {
|
||||
String tmp;
|
||||
tmp.reserve(data.size() * 3);
|
||||
|
|
@ -1123,6 +1124,7 @@ XWindowsClipboard::sendReply(Reply* reply)
|
|||
data = tmp;
|
||||
break;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
char* type = XGetAtomName(m_display, target);
|
||||
LOG((CLOG_DEBUG2 " %s (%s): %s", name, type, data.c_str()));
|
||||
|
|
|
|||
|
|
@ -577,28 +577,30 @@ Config::operator==(const Config& x) const
|
|||
return false;
|
||||
}
|
||||
|
||||
for (CellMap::const_iterator index1 = m_map.begin(),
|
||||
index2 = x.m_map.begin();
|
||||
index1 != m_map.end(); ++index1, ++index2) {
|
||||
auto index2map = x.m_map.cbegin();
|
||||
for (auto const &index1: m_map) {
|
||||
// compare names
|
||||
if (!CaselessCmp::equal(index1->first, index2->first)) {
|
||||
if (!CaselessCmp::equal(index1.first, index2map->first)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// compare cells
|
||||
if (index1->second != index2->second) {
|
||||
if (index1.second != index2map->second) {
|
||||
return false;
|
||||
}
|
||||
++index2map;
|
||||
}
|
||||
|
||||
for (NameMap::const_iterator index1 = m_nameToCanonicalName.begin(),
|
||||
index2 = x.m_nameToCanonicalName.begin();
|
||||
index1 != m_nameToCanonicalName.end();
|
||||
++index1, ++index2) {
|
||||
if (!CaselessCmp::equal(index1->first, index2->first) ||
|
||||
!CaselessCmp::equal(index1->second, index2->second)) {
|
||||
auto index2 = x.m_nameToCanonicalName.cbegin();
|
||||
for (auto const &index1: m_nameToCanonicalName) {
|
||||
if (index2 == x.m_nameToCanonicalName.cend()) {
|
||||
return false; // second source ended
|
||||
}
|
||||
if (!CaselessCmp::equal(index1.first, index2->first) ||
|
||||
!CaselessCmp::equal(index1.second, index2->second)) {
|
||||
return false;
|
||||
}
|
||||
++index2;
|
||||
}
|
||||
|
||||
// compare input filters
|
||||
|
|
@ -1755,24 +1757,25 @@ Config::Cell::operator==(const Cell& x) const
|
|||
if (m_neighbors.size() != x.m_neighbors.size()) {
|
||||
return false;
|
||||
}
|
||||
for (EdgeLinks::const_iterator index1 = m_neighbors.begin(),
|
||||
index2 = x.m_neighbors.begin();
|
||||
index1 != m_neighbors.end();
|
||||
++index1, ++index2) {
|
||||
if (index1->first != index2->first) {
|
||||
|
||||
auto index2neighbors = x.m_neighbors.cbegin();
|
||||
for (auto const &index1: m_neighbors) {
|
||||
if (index1.first != index2neighbors->first) {
|
||||
return false;
|
||||
}
|
||||
if (index1->second != index2->second) {
|
||||
if (index1.second != index2neighbors->second) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// operator== doesn't compare names. only compare destination
|
||||
// names.
|
||||
if (!CaselessCmp::equal(index1->second.getName(),
|
||||
index2->second.getName())) {
|
||||
if (!CaselessCmp::equal(index1.second.getName(),
|
||||
index2neighbors->second.getName())) {
|
||||
return false;
|
||||
}
|
||||
++index2neighbors;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ ArgParser::parseServerArgs(lib::synergy::ServerArgs& args, int argc, const char*
|
|||
{
|
||||
setArgsBase(args);
|
||||
updateCommonArgs(argv);
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
int i = 1;
|
||||
while ( i < argc) {
|
||||
if (parsePlatformArg(args, argc, argv, i)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -68,6 +68,7 @@ ArgParser::parseServerArgs(lib::synergy::ServerArgs& args, int argc, const char*
|
|||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
if (checkUnexpectedArgs()) {
|
||||
|
|
@ -83,8 +84,8 @@ ArgParser::parseClientArgs(lib::synergy::ClientArgs& args, int argc, const char*
|
|||
setArgsBase(args);
|
||||
updateCommonArgs(argv);
|
||||
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
int i {1};
|
||||
while (i < argc) {
|
||||
if (parsePlatformArg(args, argc, argv, i)) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -113,6 +114,7 @@ ArgParser::parseClientArgs(lib::synergy::ClientArgs& args, int argc, const char*
|
|||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
|
||||
return false;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
// exactly one non-option argument (server-address)
|
||||
|
|
|
|||
|
|
@ -896,7 +896,8 @@ KeyMap::keysForModifierState(KeyButton button, SInt32 group,
|
|||
// we'll assume that modifiers with higher bits are affected by modifiers
|
||||
// with lower bits. there's not much basis for that assumption except
|
||||
// that we're pretty sure shift isn't changed by other modifiers.
|
||||
for (SInt32 bit = kKeyModifierNumBits; bit-- > 0; ) {
|
||||
SInt32 bit = kKeyModifierNumBits;
|
||||
while (bit-- > 0) {
|
||||
KeyModifierMask mask = (1u << bit);
|
||||
if ((flipMask & mask) == 0) {
|
||||
// modifier is already correct
|
||||
|
|
@ -1326,20 +1327,15 @@ KeyMap::KeyItem::operator==(const KeyItem& x) const
|
|||
|
||||
KeyMap::Keystroke::Keystroke(KeyButton button,
|
||||
bool press, bool repeat, UInt32 data) :
|
||||
m_type(kButton)
|
||||
m_type(kButton), m_data{}
|
||||
{
|
||||
m_data.m_button.m_button = button;
|
||||
m_data.m_button.m_press = press;
|
||||
m_data.m_button.m_repeat = repeat;
|
||||
m_data.m_button.m_client = data;
|
||||
m_data.m_button = {button, press, repeat, data};
|
||||
}
|
||||
|
||||
KeyMap::Keystroke::Keystroke(SInt32 group, bool absolute, bool restore) :
|
||||
m_type(kGroup)
|
||||
m_type(kGroup), m_data{}
|
||||
{
|
||||
m_data.m_group.m_group = group;
|
||||
m_data.m_group.m_absolute = absolute;
|
||||
m_data.m_group.m_restore = restore;
|
||||
m_data.m_group = {group, absolute, restore};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,15 +50,15 @@ public:
|
|||
*/
|
||||
struct KeyItem {
|
||||
public:
|
||||
KeyID m_id; //!< KeyID
|
||||
SInt32 m_group; //!< Group for key
|
||||
KeyButton m_button; //!< Button to generate KeyID
|
||||
KeyModifierMask m_required; //!< Modifiers required for KeyID
|
||||
KeyModifierMask m_sensitive; //!< Modifiers key is sensitive to
|
||||
KeyModifierMask m_generates; //!< Modifiers key is mapped to
|
||||
bool m_dead; //!< \c true if this is a dead KeyID
|
||||
bool m_lock; //!< \c true if this locks a modifier
|
||||
UInt32 m_client; //!< Client data
|
||||
KeyID m_id {}; //!< KeyID
|
||||
SInt32 m_group {}; //!< Group for key
|
||||
KeyButton m_button {}; //!< Button to generate KeyID
|
||||
KeyModifierMask m_required {}; //!< Modifiers required for KeyID
|
||||
KeyModifierMask m_sensitive {}; //!< Modifiers key is sensitive to
|
||||
KeyModifierMask m_generates {}; //!< Modifiers key is mapped to
|
||||
bool m_dead {}; //!< \c true if this is a dead KeyID
|
||||
bool m_lock {}; //!< \c true if this locks a modifier
|
||||
UInt32 m_client {}; //!< Client data
|
||||
|
||||
public:
|
||||
bool operator==(const KeyItem&) const;
|
||||
|
|
@ -90,24 +90,24 @@ public:
|
|||
public:
|
||||
struct Button {
|
||||
public:
|
||||
KeyButton m_button; //!< Button to synthesize
|
||||
bool m_press; //!< \c true iff press
|
||||
bool m_repeat; //!< \c true iff for an autorepeat
|
||||
UInt32 m_client; //!< Client data
|
||||
KeyButton m_button {}; //!< Button to synthesize
|
||||
bool m_press {}; //!< \c true iff press
|
||||
bool m_repeat {}; //!< \c true iff for an autorepeat
|
||||
UInt32 m_client{}; //!< Client data
|
||||
};
|
||||
struct Group {
|
||||
public:
|
||||
SInt32 m_group; //!< Group/offset to change to/by
|
||||
bool m_absolute; //!< \c true iff change to, else by
|
||||
bool m_restore; //!< \c true iff for restoring state
|
||||
SInt32 m_group {}; //!< Group/offset to change to/by
|
||||
bool m_absolute {}; //!< \c true iff change to, else by
|
||||
bool m_restore {}; //!< \c true iff for restoring state
|
||||
};
|
||||
union Data {
|
||||
public:
|
||||
Button m_button;
|
||||
Button m_button {};
|
||||
Group m_group;
|
||||
};
|
||||
|
||||
EType m_type;
|
||||
EType m_type {};
|
||||
Data m_data;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -476,13 +476,18 @@ KeyState::sendKeyEvent(
|
|||
}
|
||||
|
||||
void
|
||||
KeyState::updateKeyMap()
|
||||
KeyState::updateKeyMap(synergy::KeyMap* existing)
|
||||
{
|
||||
// get the current keyboard map
|
||||
synergy::KeyMap keyMap;
|
||||
getKeyMap(keyMap);
|
||||
m_keyMap.swap(keyMap);
|
||||
m_keyMap.finish();
|
||||
if (existing) {
|
||||
m_keyMap.swap(*existing);
|
||||
}
|
||||
else {
|
||||
// get the current keyboard map
|
||||
synergy::KeyMap keyMap;
|
||||
getKeyMap(keyMap);
|
||||
m_keyMap.swap(keyMap);
|
||||
m_keyMap.finish();
|
||||
}
|
||||
|
||||
// add special keys
|
||||
addCombinationEntries();
|
||||
|
|
@ -823,10 +828,12 @@ KeyState::addCombinationEntries()
|
|||
{
|
||||
for (SInt32 g = 0, n = m_keyMap.getNumGroups(); g < n; ++g) {
|
||||
// add dead and compose key composition sequences
|
||||
for (const KeyID* i = s_decomposeTable; *i != 0; ++i) {
|
||||
const KeyID* i = s_decomposeTable;
|
||||
while (*i != 0) {
|
||||
// count the decomposed keys for this key
|
||||
UInt32 numKeys = 0;
|
||||
for (const KeyID* j = i; *++j != 0; ) {
|
||||
const KeyID* j = i;
|
||||
while (*++j != 0) {
|
||||
++numKeys;
|
||||
}
|
||||
|
||||
|
|
@ -835,6 +842,7 @@ KeyState::addCombinationEntries()
|
|||
|
||||
// next key
|
||||
i += numKeys + 1;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,22 +62,26 @@ public:
|
|||
|
||||
//@}
|
||||
|
||||
void updateKeyMap(synergy::KeyMap* existing);
|
||||
// IKeyState overrides
|
||||
virtual void updateKeyMap();
|
||||
virtual void updateKeyState();
|
||||
virtual void setHalfDuplexMask(KeyModifierMask);
|
||||
virtual void fakeKeyDown(KeyID id, KeyModifierMask mask,
|
||||
KeyButton button);
|
||||
virtual bool fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
||||
SInt32 count, KeyButton button);
|
||||
virtual bool fakeKeyUp(KeyButton button);
|
||||
virtual void fakeAllKeysUp();
|
||||
virtual bool fakeCtrlAltDel() = 0;
|
||||
virtual bool fakeMediaKey(KeyID id);
|
||||
void updateKeyMap() override {
|
||||
this->updateKeyMap(nullptr);
|
||||
}
|
||||
void updateKeyState() override;
|
||||
void setHalfDuplexMask(KeyModifierMask) override;
|
||||
void fakeKeyDown(KeyID id, KeyModifierMask mask,
|
||||
KeyButton button) override;
|
||||
bool fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
||||
SInt32 count, KeyButton button) override;
|
||||
bool fakeKeyUp(KeyButton button) override;
|
||||
void fakeAllKeysUp() override;
|
||||
bool fakeMediaKey(KeyID id) override;
|
||||
|
||||
virtual bool isKeyDown(KeyButton) const;
|
||||
virtual KeyModifierMask
|
||||
getActiveModifiers() const;
|
||||
bool isKeyDown(KeyButton) const override;
|
||||
KeyModifierMask
|
||||
getActiveModifiers() const override;
|
||||
// Left abstract
|
||||
virtual bool fakeCtrlAltDel() = 0;
|
||||
virtual KeyModifierMask
|
||||
pollActiveModifiers() const = 0;
|
||||
virtual SInt32 pollActiveGroup() const = 0;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
MockKeyState(const MockEventQueue& eventQueue, const MockKeyMap& keyMap) :
|
||||
MockKeyState(const MockEventQueue& eventQueue, const synergy::KeyMap& keyMap) :
|
||||
KeyState((IEventQueue*)&eventQueue, (synergy::KeyMap&)keyMap)
|
||||
{
|
||||
}
|
||||
|
|
|
|||
57
src/test/unittests/arch/IArchStringTests.cpp
Normal file
57
src/test/unittests/arch/IArchStringTests.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "lib/arch/IArchString.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
class SampleIArchString: public IArchString {
|
||||
public:
|
||||
EWideCharEncoding getWideCharEncoding() override {
|
||||
return kUTF16;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(IArchStringTests, convStringWCToMB_will_work_do_simple_conversions)
|
||||
{
|
||||
SampleIArchString as;
|
||||
char buff[20];
|
||||
bool errors;
|
||||
auto converted = as.convStringWCToMB(buff, L"Hello", 6, &errors);
|
||||
EXPECT_STREQ(buff, "Hello");
|
||||
EXPECT_EQ(converted, 6);
|
||||
EXPECT_EQ(errors, false);
|
||||
}
|
||||
|
||||
TEST(IArchStringTests, convStringWCToMB_will_work_do_simple_conversions_noresult)
|
||||
{
|
||||
SampleIArchString as;
|
||||
bool errors;
|
||||
auto converted = as.convStringWCToMB(nullptr, L"Hello", 6, &errors);
|
||||
EXPECT_EQ(converted, 6);
|
||||
EXPECT_EQ(errors, false);
|
||||
}
|
||||
|
||||
TEST(IArchStringTests, convStringMBToWC_will_work_do_simple_conversions)
|
||||
{
|
||||
SampleIArchString as;
|
||||
wchar_t buff[20];
|
||||
bool errors;
|
||||
auto converted = as.convStringMBToWC(buff, "Hello", 6, &errors);
|
||||
EXPECT_STREQ(buff, L"Hello");
|
||||
EXPECT_EQ(converted, 6);
|
||||
EXPECT_EQ(errors, false);
|
||||
}
|
||||
63
src/test/unittests/arch/unix/ArchNetworkBSDTests.cpp
Normal file
63
src/test/unittests/arch/unix/ArchNetworkBSDTests.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include "lib/arch/unix/ArchNetworkBSD.h"
|
||||
#include "lib/arch/XArch.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
TEST(ArchNetworkBSDTests, pollSocket_errs_EACCES)
|
||||
{
|
||||
ArchNetworkBSD networkBSD;
|
||||
ArchNetworkBSD::s_connectors.poll_impl = [](struct pollfd *, nfds_t, int){ errno = EACCES; return -1; };
|
||||
try {
|
||||
std::array<IArchNetwork::PollEntry,2> pe {{nullptr,0,0}};
|
||||
networkBSD.pollSocket(pe.data(), pe.size(), 1);
|
||||
FAIL() << "Expected to throw";
|
||||
}
|
||||
catch(XArchNetworkAccess const &err)
|
||||
{
|
||||
EXPECT_STREQ(err.what(), "Permission denied");
|
||||
}
|
||||
catch(std::runtime_error const &baseerr) {
|
||||
FAIL() << "Expected to throw XArchNetworkAccess but got " << baseerr.what();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ArchNetworkBSDTests, isAnyAddr_IP6)
|
||||
{
|
||||
ArchNetworkBSD networkBSD;
|
||||
std::unique_ptr<ArchNetAddressImpl> addr;
|
||||
addr.reset(networkBSD.newAnyAddr(IArchNetwork::kINET6));
|
||||
EXPECT_TRUE(networkBSD.isAnyAddr(addr.get()));
|
||||
|
||||
auto scratch = (char *)&addr->m_addr;
|
||||
scratch[2] = 'b';
|
||||
scratch[3] = 'a';
|
||||
scratch[4] = 'd';
|
||||
scratch[5] = 'a';
|
||||
scratch[6] = 'd';
|
||||
scratch[7] = 'd';
|
||||
scratch[8] = 'r';
|
||||
EXPECT_FALSE(networkBSD.isAnyAddr(addr.get()));
|
||||
}
|
||||
|
||||
#endif // #ifdnef _WIN32
|
||||
57
src/test/unittests/base/UnicodeTests.cpp
Normal file
57
src/test/unittests/base/UnicodeTests.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <array>
|
||||
#include "arch/IArchString.h"
|
||||
#include "base/Unicode.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
TEST(UnicodeTests, doUTF32ToUTF8_will_convert_simple_string)
|
||||
{
|
||||
bool errors;
|
||||
auto result = Unicode::UTF32ToUTF8(String("h\0\0\0e\0\0\0l\0\0\0l\0\0\0o\0\0\0", 20), &errors);
|
||||
EXPECT_FALSE(errors);
|
||||
EXPECT_STREQ(result.c_str(), "hello");
|
||||
}
|
||||
|
||||
TEST(UnicodeTests, doUTF16ToUTF8_will_convert_simple_string)
|
||||
{
|
||||
bool errors;
|
||||
auto result = Unicode::UTF16ToUTF8(String("h\0e\0l\0l\0o\0", 10), &errors);
|
||||
EXPECT_FALSE(errors);
|
||||
EXPECT_STREQ(result.c_str(), "hello");
|
||||
}
|
||||
|
||||
TEST(UnicodeTests, doUCS2ToUTF8_will_convert_simple_string_kUCS2)
|
||||
{
|
||||
bool errors;
|
||||
auto result = Unicode::textToUTF8("hello", &errors, IArchString::kUCS2);
|
||||
EXPECT_FALSE(errors);
|
||||
#ifdef _WIN32
|
||||
EXPECT_EQ(result, String("hello", 5)); // mixed-platform expected result
|
||||
#else
|
||||
EXPECT_EQ(result, String("h\0e\0l", 5)); // mixed-platform expected result
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
TEST(UnicodeTests, doUCS2ToUTF8_will_convert_simple_string_any_platform)
|
||||
{
|
||||
bool errors;
|
||||
auto result = Unicode::textToUTF8("hello", &errors);
|
||||
EXPECT_FALSE(errors);
|
||||
EXPECT_EQ(result, String("hello", 5)); // mixed-platform expected result
|
||||
}
|
||||
194
src/test/unittests/server/ConfigTests.cpp
Normal file
194
src/test/unittests/server/ConfigTests.cpp
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "lib/server/Config.h"
|
||||
#include "test/global/gtest.h"
|
||||
|
||||
class OnlySystemFilter: public InputFilter::Condition {
|
||||
public:
|
||||
Condition* clone() const override {
|
||||
return new OnlySystemFilter();
|
||||
}
|
||||
String format() const override {
|
||||
return "";
|
||||
}
|
||||
|
||||
InputFilter::EFilterStatus match(const Event& ev) override {
|
||||
return ev.getType() == Event::kSystem ? InputFilter::kActivate : InputFilter::kNoMatch;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_inequal_configs_with_different_map_size)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_inequal_configs_with_different_cell_names)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenB");
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_equal_configs_with_same_cell_names)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
EXPECT_TRUE(a.addScreen("screenA"));
|
||||
EXPECT_TRUE(a.addScreen("screenB"));
|
||||
EXPECT_TRUE(a.addScreen("screenC"));
|
||||
EXPECT_TRUE(a.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(a.connect("screenB", EDirection::kLeft, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(b.addScreen("screenA"));
|
||||
EXPECT_TRUE(b.addScreen("screenB"));
|
||||
EXPECT_TRUE(b.addScreen("screenC"));
|
||||
EXPECT_TRUE(b.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(b.connect("screenB", EDirection::kLeft, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
a.addOption("screenA", kOptionClipboardSharing, 1);
|
||||
b.addOption("screenA", kOptionClipboardSharing, 1);
|
||||
a.addOption(std::string(), kOptionClipboardSharing, 1);
|
||||
b.addOption(std::string(), kOptionClipboardSharing, 1);
|
||||
a.getInputFilter()->addFilterRule(InputFilter::Rule{new OnlySystemFilter()});
|
||||
b.getInputFilter()->addFilterRule(InputFilter::Rule{new OnlySystemFilter()});
|
||||
a.addAlias("screenA", "aliasA");
|
||||
b.addAlias("screenA", "aliasA");
|
||||
a.setSynergyAddress(NetworkAddress(8080));
|
||||
b.setSynergyAddress(NetworkAddress(8080));
|
||||
|
||||
EXPECT_TRUE(a == b);
|
||||
EXPECT_TRUE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_same_cell_names_different_options)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
a.addOption("screenA", kOptionClipboardSharing, 0);
|
||||
b.addOption("screenA", kOptionClipboardSharing, 1);
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_same_cell_names_different_aliases1)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
b.addAlias("screenA", "aliasA");
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_same_cell_names_different_aliases2)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
a.addAlias("screenA", "aliasA");
|
||||
b.addAlias("screenA", "aliasB");
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_different_global_options)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
a.addOption(std::string(), kOptionClipboardSharing, 0);
|
||||
b.addOption(std::string(), kOptionClipboardSharing, 1);
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_different_filters)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
a.getInputFilter()->addFilterRule(InputFilter::Rule{new OnlySystemFilter()});
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_configs_with_different_address)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
a.addScreen("screenA");
|
||||
b.addScreen("screenA");
|
||||
a.setSynergyAddress(NetworkAddress(8080));
|
||||
b.setSynergyAddress(NetworkAddress(1010));
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_cell_neighbours1)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
EXPECT_TRUE(a.addScreen("screenA"));
|
||||
EXPECT_TRUE(a.addScreen("screenB"));
|
||||
EXPECT_TRUE(a.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(b.addScreen("screenA"));
|
||||
EXPECT_TRUE(b.addScreen("screenB"));
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_cell_neighbours2)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
EXPECT_TRUE(a.addScreen("screenA"));
|
||||
EXPECT_TRUE(a.addScreen("screenB"));
|
||||
EXPECT_TRUE(a.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(b.addScreen("screenA"));
|
||||
EXPECT_TRUE(b.addScreen("screenB"));
|
||||
EXPECT_TRUE(b.connect("screenA", EDirection::kBottom, 0.0f, 0.25f, "screenB", 0.25f, 1.0f));
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
||||
TEST(ServerConfigTests, serverconfig_will_deem_different_cell_neighbours3)
|
||||
{
|
||||
Config a(nullptr);
|
||||
Config b(nullptr);
|
||||
EXPECT_TRUE(a.addScreen("screenA"));
|
||||
EXPECT_TRUE(a.addScreen("screenB"));
|
||||
EXPECT_TRUE(a.addScreen("screenC"));
|
||||
EXPECT_TRUE(a.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenB", 0.5f, 1.0f));
|
||||
EXPECT_TRUE(b.addScreen("screenA"));
|
||||
EXPECT_TRUE(b.addScreen("screenB"));
|
||||
EXPECT_TRUE(b.addScreen("screenC"));
|
||||
EXPECT_TRUE(b.connect("screenA", EDirection::kBottom, 0.0f, 0.5f, "screenC", 0.5f, 1.0f));
|
||||
EXPECT_FALSE(a == b);
|
||||
EXPECT_FALSE(b == a);
|
||||
}
|
||||
|
|
@ -214,5 +214,27 @@ TEST(KeyMapTests, isCommand_superMask_returnTrue)
|
|||
|
||||
EXPECT_EQ(true, keyMap.isCommand(mask));
|
||||
}
|
||||
|
||||
|
||||
TEST(KeyMapTests, mapkey_handles_setmodifier_with_no_mapped)
|
||||
{
|
||||
KeyMap keyMap {};
|
||||
KeyMap::Keystroke stroke('A', true, false, 1);
|
||||
KeyMap::KeyItem keyItem;
|
||||
keyItem.m_button = 'A';
|
||||
keyItem.m_group = 1;
|
||||
keyItem.m_id = 'A';
|
||||
keyMap.addKeyEntry(keyItem);
|
||||
keyMap.finish();
|
||||
KeyMap::Keystrokes strokes {stroke};
|
||||
KeyMap::ModifierToKeys activeModifiers {};
|
||||
KeyModifierMask currentState {};
|
||||
KeyModifierMask desiredMask {};
|
||||
auto result = keyMap.mapKey(strokes, kKeySetModifiers, 1, activeModifiers, currentState, desiredMask, false);
|
||||
EXPECT_FALSE(result == nullptr);
|
||||
desiredMask = KeyModifierControl;
|
||||
result = keyMap.mapKey(strokes, kKeySetModifiers, 1, activeModifiers, currentState, desiredMask, false);
|
||||
EXPECT_TRUE(result == nullptr);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,6 +463,22 @@ TEST(KeyStateTests, isKeyDown_noKeysDown_returnsFalse)
|
|||
ASSERT_FALSE(actual);
|
||||
}
|
||||
|
||||
TEST(KeyStateTests, updateKeyMap_exercised)
|
||||
{
|
||||
synergy::KeyMap keyMap;
|
||||
synergy::KeyMap::KeyItem keyItem;
|
||||
keyItem.m_button = 'A';
|
||||
keyItem.m_group = 1;
|
||||
keyItem.m_id = 'A';
|
||||
keyMap.addKeyEntry(keyItem);
|
||||
keyMap.finish();
|
||||
MockEventQueue eventQueue;
|
||||
KeyStateImpl keyState(eventQueue, keyMap);
|
||||
|
||||
keyState.updateKeyMap(&keyMap);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stubPollPressedKeys(IKeyState::KeyButtonSet& pressedKeys)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue