diff --git a/include_ut/f1x/aasdk/USB/UT/ConnectedAccessoriesEnumeratorPromiseHandler.mock.hpp b/include_ut/f1x/aasdk/USB/UT/ConnectedAccessoriesEnumeratorPromiseHandler.mock.hpp
new file mode 100644
index 0000000..23c45ec
--- /dev/null
+++ b/include_ut/f1x/aasdk/USB/UT/ConnectedAccessoriesEnumeratorPromiseHandler.mock.hpp
@@ -0,0 +1,44 @@
+/*
+* This file is part of aasdk library project.
+* Copyright (C) 2018 f1x.studio (Michal Szwaj)
+*
+* aasdk is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+
+* aasdk 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 aasdk. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace f1x
+{
+namespace aasdk
+{
+namespace usb
+{
+namespace ut
+{
+
+class ConnectedAccessoriesEnumeratorPromiseHandlerMock
+{
+public:
+ MOCK_METHOD1(onResolve, void(bool result));
+ MOCK_METHOD1(onReject, void(const error::Error& e));
+};
+
+}
+}
+}
+}
diff --git a/src/USB/ConnectedAccessoriesEnumerator.ut.cpp b/src/USB/ConnectedAccessoriesEnumerator.ut.cpp
new file mode 100644
index 0000000..297b4d4
--- /dev/null
+++ b/src/USB/ConnectedAccessoriesEnumerator.ut.cpp
@@ -0,0 +1,211 @@
+/*
+* This file is part of aasdk library project.
+* Copyright (C) 2018 f1x.studio (Michal Szwaj)
+*
+* aasdk is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+
+* aasdk 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 aasdk. If not, see .
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace f1x
+{
+namespace aasdk
+{
+namespace usb
+{
+namespace ut
+{
+
+using ::testing::_;
+using ::testing::SetArgReferee;
+using ::testing::Return;
+using ::testing::SaveArg;
+
+class ConnectedAccessoriesEnumeratorUnitTest
+{
+protected:
+ ConnectedAccessoriesEnumeratorUnitTest()
+ : queryChain_(&queryChainMock_, [](auto*) {})
+ , deviceListHandle_(&deviceList_, [](auto*) {})
+ , device_(reinterpret_cast(-1))
+ , deviceHandle_(reinterpret_cast(&dummyDeviceHandle_), [](auto*) {})
+ , promise_(IConnectedAccessoriesEnumerator::Promise::defer(ioService_))
+ {
+ promise_->then(std::bind(&ConnectedAccessoriesEnumeratorPromiseHandlerMock::onResolve, &promiseHandlerMock_, std::placeholders::_1),
+ std::bind(&ConnectedAccessoriesEnumeratorPromiseHandlerMock::onReject, &promiseHandlerMock_, std::placeholders::_1));
+ }
+
+ boost::asio::io_service ioService_;
+ USBWrapperMock usbWrapperMock_;
+ AccessoryModeQueryChainFactoryMock queryChainFactoryMock_;
+ AccessoryModeQueryChainMock queryChainMock_;
+ IAccessoryModeQueryChain::Pointer queryChain_;
+ DeviceList deviceList_;
+ DeviceListHandle deviceListHandle_;
+ libusb_device* device_;
+ USBWrapperMock::DummyDeviceHandle dummyDeviceHandle_;
+ DeviceHandle deviceHandle_;
+ ConnectedAccessoriesEnumeratorPromiseHandlerMock promiseHandlerMock_;
+ IConnectedAccessoriesEnumerator::Promise::Pointer promise_;
+};
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_FirstDeviceIsAOAPCapables, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ deviceList_.push_back(reinterpret_cast(1));
+ EXPECT_CALL(queryChainFactoryMock_, create()).WillOnce(Return(queryChain_));
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(0)));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ EXPECT_CALL(usbWrapperMock_, open(*deviceList_.begin(), _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle_), Return(0)));
+
+ IAccessoryModeQueryChain::Promise::Pointer queryChainPromise;
+ EXPECT_CALL(queryChainMock_, start(deviceHandle_, _)).WillOnce(SaveArg<1>(&queryChainPromise));
+ ioService_.run();
+ ioService_.reset();
+
+ EXPECT_CALL(promiseHandlerMock_, onResolve(true));
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+ queryChainPromise->resolve(deviceHandle_);
+ ioService_.run();
+}
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_SecondDeviceIsAOAPCapable, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ deviceList_.push_back(reinterpret_cast(1));
+ deviceList_.push_back(reinterpret_cast(2));
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+
+ EXPECT_CALL(queryChainFactoryMock_, create()).Times(deviceList_.size()).WillRepeatedly(Return(queryChain_));
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(0)));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ EXPECT_CALL(usbWrapperMock_, open(*deviceList_.begin(), _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle_), Return(0)));
+ IAccessoryModeQueryChain::Promise::Pointer queryChainPromise;
+ EXPECT_CALL(queryChainMock_, start(deviceHandle_, _)).WillRepeatedly(SaveArg<1>(&queryChainPromise));
+ ioService_.run();
+ ioService_.reset();
+
+ EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0);
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+
+ // open second device
+ USBWrapperMock::DummyDeviceHandle dummyDeviceHandle2;
+ DeviceHandle deviceHandle2(reinterpret_cast(&dummyDeviceHandle2), [](auto*) {});
+ EXPECT_CALL(usbWrapperMock_, open(*(++deviceList_.begin()), _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle2), Return(0)));
+
+ IAccessoryModeQueryChain::Promise::Pointer queryChainPromise2;
+ EXPECT_CALL(queryChainMock_, start(deviceHandle2, _)).WillRepeatedly(SaveArg<1>(&queryChainPromise2));
+
+ queryChainPromise->reject(error::Error(error::ErrorCode::USB_AOAP_PROTOCOL_VERSION));
+ ioService_.run();
+ ioService_.reset();
+
+ EXPECT_CALL(promiseHandlerMock_, onResolve(true));
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+ queryChainPromise2->resolve(deviceHandle2);
+ ioService_.run();
+}
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_NoAOAPCapableDevice, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ for(size_t i = 1; i < 1000; ++i)
+ {
+ deviceList_.push_back(reinterpret_cast(i));
+ }
+
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(0)));
+ EXPECT_CALL(queryChainFactoryMock_, create()).Times(deviceList_.size()).WillRepeatedly(Return(queryChain_));
+
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ EXPECT_CALL(promiseHandlerMock_, onResolve(false));
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+
+ for(const auto& device : deviceList_)
+ {
+ USBWrapperMock::DummyDeviceHandle dummyDeviceHandle;
+ DeviceHandle deviceHandle(reinterpret_cast(&dummyDeviceHandle), [](auto*) {});
+ EXPECT_CALL(usbWrapperMock_, open(device, _)).WillOnce(DoAll(SetArgReferee<1>(deviceHandle), Return(0)));
+
+ IAccessoryModeQueryChain::Promise::Pointer queryChainPromise;
+ EXPECT_CALL(queryChainMock_, start(deviceHandle, _)).WillRepeatedly(SaveArg<1>(&queryChainPromise));
+
+ ioService_.run();
+ ioService_.reset();
+
+ queryChainPromise->reject(error::Error(error::ErrorCode::USB_AOAP_PROTOCOL_VERSION));
+ }
+
+ ioService_.run();
+}
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_GetDeviceListFailed, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(-1)));
+ EXPECT_CALL(promiseHandlerMock_, onResolve(_)).Times(0);
+ EXPECT_CALL(promiseHandlerMock_, onReject(error::Error(error::ErrorCode::USB_LIST_DEVICES)));
+
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ ioService_.run();
+}
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_EmptyDevicesList, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(0)));
+ EXPECT_CALL(promiseHandlerMock_, onResolve(false));
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ ioService_.run();
+}
+
+BOOST_FIXTURE_TEST_CASE(ConnectedAccessoriesEnumerator_OpenDeviceFailed, ConnectedAccessoriesEnumeratorUnitTest)
+{
+ for(size_t i = 1; i < 1000; ++i)
+ {
+ deviceList_.push_back(reinterpret_cast(i));
+ }
+
+ EXPECT_CALL(usbWrapperMock_, getDeviceList(_)).WillOnce(DoAll(SetArgReferee<0>(deviceListHandle_), Return(0)));
+
+ auto connectedAccessoriesEnumerator(std::make_shared(usbWrapperMock_, ioService_, queryChainFactoryMock_));
+ connectedAccessoriesEnumerator->enumerate(std::move(promise_));
+
+ EXPECT_CALL(promiseHandlerMock_, onResolve(false));
+ EXPECT_CALL(promiseHandlerMock_, onReject(_)).Times(0);
+
+ for(const auto& device : deviceList_)
+ {
+ EXPECT_CALL(usbWrapperMock_, open(device, _)).WillOnce(DoAll(SetArgReferee<1>(nullptr), Return(0xFFF)));
+ }
+
+ ioService_.run();
+}
+
+}
+}
+}
+}