#include "JsonRpcAdaptor.h" #include "JsonRpc.h" #include Q_DECLARE_METATYPE(QVariant); class TestObject : public QObject { Q_OBJECT; Q_CLASSINFO("JsonQt-RPC-name", "TestName"); Q_CLASSINFO("JsonQt-RPC-id", "urn:data:test"); Q_CLASSINFO("JsonQt-RPC-version", "9000.001"); Q_CLASSINFO("JsonQt-RPC-summary", "Ponies"); public: TestObject(QObject* parent) : QObject(parent) {} public slots: void functionOne(const QString& foo) { emit functionOneCalled(foo); } QString functionTwo() { emit functionTwoCalled(); return "Mary had a little lamb."; } void functionThree(int one, bool two, QVariantList three, QVariantMap four) { emit functionThreeCalled(one, two, three, four); } void functionFour(const QString& foo, const QString& bar) { emit functionFourCalled(foo, bar); } signals: void functionOneCalled(const QString& foo); void functionTwoCalled(); void functionThreeCalled(int, bool, QVariantList, QVariantMap); void functionFourCalled(QString, QString); }; class JsonRpcAdaptor : public QObject { Q_OBJECT private slots: void initTestCase() { qRegisterMetaType("QVariant"); m_testObject = new TestObject(this); m_adaptor = new JsonQt::JsonRpcAdaptor(m_testObject, this); m_rpc = new JsonQt::JsonRpc(this); connect( m_rpc, SIGNAL(sendJson(const QString&)), m_adaptor, SLOT(processJson(const QString&)) ); connect( m_adaptor, SIGNAL(sendJson(const QString&)), m_rpc, SLOT(processJson(const QString&)) ); } void testFunctionOne() { QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionOneCalled(const QString&))); QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&))); QVariantMap parameters; parameters["foo"] = "bar"; m_rpc->sendRequest(42, "functionOne", parameters); QCOMPARE(testObjectSpy.count(), 1); QCOMPARE(testObjectSpy.first().first().toString(), QString("bar")); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant(42)); QCOMPARE(rpcSpy.first().value(1).value(), QVariant()); } void testFunctionFour() { QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionFourCalled(QString, QString))); QVariantMap parameters; parameters["foo"] = "bar"; parameters["bar"] = "baz"; m_rpc->sendRequest(123, "functionFour", parameters); QCOMPARE(testObjectSpy.count(), 1); QCOMPARE(testObjectSpy.first().value(0).toString(), QString("bar")); QCOMPARE(testObjectSpy.first().value(1).toString(), QString("baz")); } void testFunctionTwo() { QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionTwoCalled())); QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&))); m_rpc->sendRequest(1337, "functionTwo"); QCOMPARE(testObjectSpy.count(), 1); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant(1337)); QCOMPARE(rpcSpy.first().value(1).value().toString(), QString("Mary had a little lamb.")); } void testFunctionThree() { QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionThreeCalled(int, bool, QVariantList, QVariantMap))); QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&))); QVariantList listParameter; QVariantMap nestedMap; nestedMap["foo"] = "bar"; listParameter.append(nestedMap); listParameter.append("baz"); QVariantList parameters; parameters.append(123); parameters.append(true); parameters.append(listParameter); parameters.append(nestedMap); m_rpc->sendRequest(42, "functionThree", parameters); QCOMPARE(testObjectSpy.count(), 1); QVariantList result = testObjectSpy.first(); QCOMPARE(result.value(0), QVariant(123)); QCOMPARE(result.value(1), QVariant(true)); QCOMPARE(result.value(2), QVariant(listParameter)); QCOMPARE(result.value(3), QVariant(nestedMap)); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant(42)); QCOMPARE(rpcSpy.first().value(1).value(), QVariant()); } void testInvalidFunction() { QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant))); m_rpc->sendRequest("123", "DOES NOT EXIST"); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant("123")); QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::MethodNotFound)); } void testBadArgumentCount() { QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant))); m_rpc->sendRequest("123", "functionOne"); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant("123")); QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters)); } void testWrongArgumentTypes() { QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant))); QVariantMap parameters; parameters["foo"] = 123; m_rpc->sendRequest("123", "functionOne", parameters); QCOMPARE(rpcSpy.count(), 1); QCOMPARE(rpcSpy.first().value(0).value(), QVariant("123")); QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters)); } void testIntropection() { QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&))); m_rpc->sendRequest(QVariant(), "system.describe"); QCOMPARE(rpcSpy.count(), 1); QVariantMap introspectionData = rpcSpy.first().value(1).value().toMap(); QVERIFY(!introspectionData.isEmpty()); // Service data QCOMPARE(introspectionData.value("sdversion").toString(), QString("1.0")); // Service Description version QCOMPARE(introspectionData.value("name").toString(), QString("TestName")); QCOMPARE(introspectionData.value("id").toString(), QString("urn:data:test")); QCOMPARE(introspectionData.value("version").toString(), QString("9000.001")); QCOMPARE(introspectionData.value("summary").toString(), QString("Ponies")); QVERIFY(!introspectionData.contains("help")); QVERIFY(introspectionData.contains("procs")); // Method data QVariantList methods = introspectionData.value("procs").toList(); QCOMPARE(methods.count(), 4); QVariantMap functionOne = methods.takeFirst().toMap(); QVariantMap functionTwo = methods.takeFirst().toMap(); QVariantMap functionThree = methods.takeFirst().toMap(); QVariantMap functionFour = methods.takeFirst().toMap(); QVariantList params; QVariantMap param; // functionOne QCOMPARE(functionOne.value("name").toString(), QString("functionOne")); QCOMPARE(functionOne.value("return").toString(), QString("nil")); params = functionOne.value("params").toList(); QCOMPARE(params.count(), 1); param = params.first().toMap(); QCOMPARE(param.value("name").toString(), QString("foo")); QCOMPARE(param.value("type").toString(), QString("str")); // functionTwo QCOMPARE(functionTwo.value("name").toString(), QString("functionTwo")); QCOMPARE(functionTwo.value("return").toString(), QString("str")); params = functionTwo.value("params").toList(); QCOMPARE(params.count(), 0); // functionThree QCOMPARE(functionThree.value("name").toString(), QString("functionThree")); QCOMPARE(functionThree.value("return").toString(), QString("nil")); params = functionThree.value("params").toList(); QCOMPARE(params.count(), 4); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("one")); QCOMPARE(param.value("type").toString(), QString("num")); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("two")); QCOMPARE(param.value("type").toString(), QString("bit")); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("three")); QCOMPARE(param.value("type").toString(), QString("arr")); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("four")); QCOMPARE(param.value("type").toString(), QString("obj")); // functionFour QCOMPARE(functionFour.value("name").toString(), QString("functionFour")); QCOMPARE(functionFour.value("return").toString(), QString("nil")); params = functionFour.value("params").toList(); QCOMPARE(params.count(), 2); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("foo")); QCOMPARE(param.value("type").toString(), QString("str")); param = params.takeFirst().toMap(); QCOMPARE(param.value("name").toString(), QString("bar")); QCOMPARE(param.value("type").toString(), QString("str")); } private: JsonQt::JsonRpc* m_rpc; JsonQt::JsonRpcAdaptor* m_adaptor; TestObject* m_testObject; }; QTEST_MAIN(JsonRpcAdaptor); #include "moc_JsonRpcAdaptor.cxx"