File indexing completed on 2025-01-05 05:00:01
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 0007 #include <testlib/qtest_zanshin.h> 0008 0009 #include "utils/dependencymanager.h" 0010 0011 using namespace Utils; 0012 0013 class Interface0 0014 { 0015 public: 0016 typedef QSharedPointer<Interface0> Ptr; 0017 0018 Interface0() {} 0019 virtual ~Interface0() {} 0020 virtual void doSomething() = 0; 0021 }; 0022 0023 class FirstImplementation0 : public Interface0 0024 { 0025 public: 0026 void doSomething() override { qDebug() << "FirstImplementation"; } 0027 }; 0028 0029 class SecondImplementation0 : public Interface0 0030 { 0031 public: 0032 void doSomething() override { qDebug() << "SecondImplementation"; } 0033 }; 0034 0035 #define DECLARE_IMPLEMENTED_INTERFACE(N) \ 0036 class Interface##N \ 0037 { \ 0038 public: \ 0039 typedef QSharedPointer<Interface##N> Ptr; \ 0040 \ 0041 Interface##N() {} \ 0042 virtual ~Interface##N() {} \ 0043 virtual void doSomething() = 0; \ 0044 }; \ 0045 \ 0046 class Implementation##N : public Interface##N \ 0047 { \ 0048 public: \ 0049 void doSomething() override { qDebug() << "Implementation##N"; } \ 0050 }; 0051 0052 DECLARE_IMPLEMENTED_INTERFACE(1) 0053 DECLARE_IMPLEMENTED_INTERFACE(2) 0054 DECLARE_IMPLEMENTED_INTERFACE(3) 0055 DECLARE_IMPLEMENTED_INTERFACE(4) 0056 DECLARE_IMPLEMENTED_INTERFACE(5) 0057 DECLARE_IMPLEMENTED_INTERFACE(6) 0058 DECLARE_IMPLEMENTED_INTERFACE(7) 0059 DECLARE_IMPLEMENTED_INTERFACE(8) 0060 DECLARE_IMPLEMENTED_INTERFACE(9) 0061 DECLARE_IMPLEMENTED_INTERFACE(10) 0062 DECLARE_IMPLEMENTED_INTERFACE(11) 0063 DECLARE_IMPLEMENTED_INTERFACE(12) 0064 DECLARE_IMPLEMENTED_INTERFACE(13) 0065 DECLARE_IMPLEMENTED_INTERFACE(14) 0066 0067 class AnotherInterface 0068 { 0069 public: 0070 AnotherInterface() {} 0071 virtual ~AnotherInterface() {} 0072 virtual void doSomethingDelegated() = 0; 0073 }; 0074 0075 class AnotherFirstImplementation : public AnotherInterface 0076 { 0077 public: 0078 explicit AnotherFirstImplementation(const Interface0::Ptr &iface) 0079 : m_iface(iface) {} 0080 0081 void doSomethingDelegated() override { m_iface->doSomething(); } 0082 0083 Interface0::Ptr iface() const { return m_iface; } 0084 0085 private: 0086 Interface0::Ptr m_iface; 0087 }; 0088 0089 class AnotherSecondImplementation : public AnotherInterface 0090 { 0091 public: 0092 AnotherSecondImplementation(Interface0::Ptr iface0, 0093 Interface1::Ptr iface1, 0094 Interface2::Ptr iface2, 0095 Interface3::Ptr iface3, 0096 Interface4::Ptr iface4, 0097 Interface5::Ptr iface5, 0098 Interface6::Ptr iface6, 0099 Interface7::Ptr iface7, 0100 Interface8::Ptr iface8, 0101 Interface9::Ptr iface9, 0102 Interface10::Ptr iface10, 0103 Interface11::Ptr iface11, 0104 Interface12::Ptr iface12, 0105 Interface13::Ptr iface13, 0106 Interface14::Ptr iface14) 0107 : m_iface0(iface0), 0108 m_iface1(iface1), 0109 m_iface2(iface2), 0110 m_iface3(iface3), 0111 m_iface4(iface4), 0112 m_iface5(iface5), 0113 m_iface6(iface6), 0114 m_iface7(iface7), 0115 m_iface8(iface8), 0116 m_iface9(iface9), 0117 m_iface10(iface10), 0118 m_iface11(iface11), 0119 m_iface12(iface12), 0120 m_iface13(iface13), 0121 m_iface14(iface14) 0122 { 0123 } 0124 0125 void doSomethingDelegated() override { m_iface1->doSomething(); } 0126 0127 Interface0::Ptr iface0() const { return m_iface0; } 0128 Interface1::Ptr iface1() const { return m_iface1; } 0129 Interface2::Ptr iface2() const { return m_iface2; } 0130 Interface3::Ptr iface3() const { return m_iface3; } 0131 Interface4::Ptr iface4() const { return m_iface4; } 0132 Interface5::Ptr iface5() const { return m_iface5; } 0133 Interface6::Ptr iface6() const { return m_iface6; } 0134 Interface7::Ptr iface7() const { return m_iface7; } 0135 Interface8::Ptr iface8() const { return m_iface8; } 0136 Interface9::Ptr iface9() const { return m_iface9; } 0137 Interface10::Ptr iface10() const { return m_iface10; } 0138 Interface11::Ptr iface11() const { return m_iface11; } 0139 Interface12::Ptr iface12() const { return m_iface12; } 0140 Interface13::Ptr iface13() const { return m_iface13; } 0141 Interface14::Ptr iface14() const { return m_iface14; } 0142 0143 private: 0144 Interface0::Ptr m_iface0; 0145 Interface1::Ptr m_iface1; 0146 Interface2::Ptr m_iface2; 0147 Interface3::Ptr m_iface3; 0148 Interface4::Ptr m_iface4; 0149 Interface5::Ptr m_iface5; 0150 Interface6::Ptr m_iface6; 0151 Interface7::Ptr m_iface7; 0152 Interface8::Ptr m_iface8; 0153 Interface9::Ptr m_iface9; 0154 Interface10::Ptr m_iface10; 0155 Interface11::Ptr m_iface11; 0156 Interface12::Ptr m_iface12; 0157 Interface13::Ptr m_iface13; 0158 Interface14::Ptr m_iface14; 0159 }; 0160 0161 class DependencyManagerTest : public QObject 0162 { 0163 Q_OBJECT 0164 private: 0165 static bool s_firstImplFactoryCalled; 0166 static DependencyManager *s_manager; 0167 0168 static Interface0 *firstImplFactory(DependencyManager *manager) 0169 { 0170 s_firstImplFactoryCalled = true; 0171 s_manager = manager; 0172 return new FirstImplementation0; 0173 } 0174 0175 private slots: 0176 void shouldMemorizeDependency() 0177 { 0178 DependencyManager deps; 0179 deps.add<Interface0, FirstImplementation0>(); 0180 auto object1 = deps.create<Interface0>(); 0181 QVERIFY(object1.dynamicCast<FirstImplementation0>()); 0182 auto object2 = deps.create<Interface0>(); 0183 QVERIFY(object2.dynamicCast<FirstImplementation0>()); 0184 QVERIFY(object1 != object2); 0185 } 0186 0187 void shouldAllowOurOwnFactory() 0188 { 0189 s_firstImplFactoryCalled = false; 0190 s_manager = nullptr; 0191 DependencyManager deps; 0192 deps.add<Interface0>(&DependencyManagerTest::firstImplFactory); 0193 auto object = deps.create<Interface0>(); 0194 QVERIFY(object.dynamicCast<FirstImplementation0>()); 0195 QVERIFY(s_firstImplFactoryCalled); 0196 QVERIFY(s_manager == &deps); 0197 } 0198 0199 void shouldAllowUniqueInstances() 0200 { 0201 DependencyManager deps; 0202 deps.add<Interface0, FirstImplementation0, DependencyManager::UniqueInstance>(); 0203 auto object1 = deps.create<Interface0>(); 0204 QVERIFY(object1.dynamicCast<FirstImplementation0>()); 0205 auto object2 = deps.create<Interface0>(); 0206 QVERIFY(object2.dynamicCast<FirstImplementation0>()); 0207 QVERIFY(object1 == object2); 0208 } 0209 0210 void shouldAllowUniqueInstancesWithOurOwnFactory() 0211 { 0212 s_firstImplFactoryCalled = false; 0213 s_manager = nullptr; 0214 DependencyManager deps; 0215 deps.add<Interface0, DependencyManager::UniqueInstance>(&DependencyManagerTest::firstImplFactory); 0216 auto object1 = deps.create<Interface0>(); 0217 QVERIFY(object1.dynamicCast<FirstImplementation0>()); 0218 auto object2 = deps.create<Interface0>(); 0219 QVERIFY(object2.dynamicCast<FirstImplementation0>()); 0220 QVERIFY(s_firstImplFactoryCalled); 0221 QVERIFY(s_manager == &deps); 0222 QVERIFY(object1 == object2); 0223 } 0224 0225 void shouldAllowOurOwnFactoryAsLambda() 0226 { 0227 #ifdef Q_COMPILER_LAMBDA 0228 bool ownFactoryCalled = false; 0229 DependencyManager *managerCalled = nullptr; 0230 0231 DependencyManager deps; 0232 deps.add<Interface0>([&](DependencyManager *manager) -> Interface0* { 0233 ownFactoryCalled = true; 0234 managerCalled = manager; 0235 return new FirstImplementation0; 0236 }); 0237 auto object = deps.create<Interface0>(); 0238 QVERIFY(object.dynamicCast<FirstImplementation0>()); 0239 QVERIFY(ownFactoryCalled); 0240 QVERIFY(managerCalled == &deps); 0241 #endif 0242 } 0243 0244 void shouldMakeManagerSpecificDependencies() 0245 { 0246 DependencyManager deps1; 0247 deps1.add<Interface0, FirstImplementation0>(); 0248 DependencyManager deps2; 0249 deps2.add<Interface0, SecondImplementation0>(); 0250 0251 auto object1 = deps1.create<Interface0>(); 0252 auto object2 = deps2.create<Interface0>(); 0253 0254 QVERIFY(object1.dynamicCast<FirstImplementation0>()); 0255 QVERIFY(object2.dynamicCast<SecondImplementation0>()); 0256 } 0257 0258 void shouldCleanupProviders() 0259 { 0260 QCOMPARE(Internal::Supplier<Interface0>::providersCount(), 0); 0261 0262 { 0263 DependencyManager deps1; 0264 deps1.add<Interface0, FirstImplementation0>(); 0265 QCOMPARE(Internal::Supplier<Interface0>::providersCount(), 1); 0266 0267 { 0268 DependencyManager deps2; 0269 deps2.add<Interface0, SecondImplementation0>(); 0270 QCOMPARE(Internal::Supplier<Interface0>::providersCount(), 2); 0271 } 0272 0273 QCOMPARE(Internal::Supplier<Interface0>::providersCount(), 1); 0274 } 0275 0276 QCOMPARE(Internal::Supplier<Interface0>::providersCount(), 0); 0277 } 0278 0279 void shouldInjectDependencyInConstructor() 0280 { 0281 DependencyManager deps; 0282 deps.add<Interface0, FirstImplementation0>(); 0283 deps.add<AnotherInterface, AnotherFirstImplementation(Interface0*)>(); 0284 0285 auto object = deps.create<AnotherInterface>(); 0286 auto impl = object.dynamicCast<AnotherFirstImplementation>(); 0287 QVERIFY(impl != nullptr); 0288 QVERIFY(impl->iface().dynamicCast<FirstImplementation0>()); 0289 } 0290 0291 void shouldInjectDependenciesInConstructor() 0292 { 0293 DependencyManager deps; 0294 deps.add<Interface0, FirstImplementation0>(); 0295 deps.add<Interface1, Implementation1>(); 0296 deps.add<Interface2, Implementation2>(); 0297 deps.add<Interface3, Implementation3>(); 0298 deps.add<Interface4, Implementation4>(); 0299 deps.add<Interface5, Implementation5>(); 0300 deps.add<Interface6, Implementation6>(); 0301 deps.add<Interface7, Implementation7>(); 0302 deps.add<Interface8, Implementation8>(); 0303 deps.add<Interface9, Implementation9>(); 0304 deps.add<Interface10, Implementation10>(); 0305 deps.add<Interface11, Implementation11>(); 0306 deps.add<Interface12, Implementation12>(); 0307 deps.add<Interface13, Implementation13>(); 0308 deps.add<Interface14, Implementation14>(); 0309 deps.add<AnotherInterface, AnotherSecondImplementation(Interface0*, 0310 Interface1*, 0311 Interface2*, 0312 Interface3*, 0313 Interface4*, 0314 Interface5*, 0315 Interface6*, 0316 Interface7*, 0317 Interface8*, 0318 Interface9*, 0319 Interface10*, 0320 Interface11*, 0321 Interface12*, 0322 Interface13*, 0323 Interface14*)>(); 0324 auto object = deps.create<AnotherInterface>(); 0325 auto impl = object.dynamicCast<AnotherSecondImplementation>(); 0326 QVERIFY(impl != nullptr); 0327 QVERIFY(impl->iface0().dynamicCast<FirstImplementation0>()); 0328 QVERIFY(impl->iface1().dynamicCast<Implementation1>()); 0329 QVERIFY(impl->iface2().dynamicCast<Implementation2>()); 0330 QVERIFY(impl->iface3().dynamicCast<Implementation3>()); 0331 QVERIFY(impl->iface4().dynamicCast<Implementation4>()); 0332 QVERIFY(impl->iface5().dynamicCast<Implementation5>()); 0333 QVERIFY(impl->iface6().dynamicCast<Implementation6>()); 0334 QVERIFY(impl->iface7().dynamicCast<Implementation7>()); 0335 QVERIFY(impl->iface8().dynamicCast<Implementation8>()); 0336 QVERIFY(impl->iface9().dynamicCast<Implementation9>()); 0337 QVERIFY(impl->iface10().dynamicCast<Implementation10>()); 0338 QVERIFY(impl->iface11().dynamicCast<Implementation11>()); 0339 QVERIFY(impl->iface12().dynamicCast<Implementation12>()); 0340 QVERIFY(impl->iface13().dynamicCast<Implementation13>()); 0341 QVERIFY(impl->iface14().dynamicCast<Implementation14>()); 0342 } 0343 }; 0344 0345 bool DependencyManagerTest::s_firstImplFactoryCalled = false; 0346 DependencyManager *DependencyManagerTest::s_manager = nullptr; 0347 0348 ZANSHIN_TEST_MAIN(DependencyManagerTest) 0349 0350 #include "dependencymanagertest.moc"