/ test / tst_neovimconnector.cpp
tst_neovimconnector.cpp
  1  #include <QTest>
  2  #include <QSignalSpy>
  3  #include <QTcpServer>
  4  #include <QTcpSocket>
  5  #include <QRegularExpression>
  6  #include <QBuffer>
  7  
  8  #include <neovimconnector.h>
  9  #include "common.h"
 10  
 11  namespace NeovimQt {
 12  
 13  class Test: public QObject
 14  {
 15  	Q_OBJECT
 16  private slots:
 17  
 18  	void reconnect() {
 19  		NeovimConnector c(new QBuffer());
 20  		QCOMPARE(c.canReconnect(), false);
 21  
 22  		NeovimConnector *spawned = NeovimConnector::spawn({"-u", "NONE"});
 23  		spawned->setParent(this);
 24  		QCOMPARE(spawned->connectionType(), NeovimConnector::SpawnedConnection);
 25  		QCOMPARE(spawned->canReconnect(), true);
 26  
 27  		spawned->reconnect();
 28  	}
 29  
 30  	void isReady() {
 31  
 32  		NeovimConnector *c = NeovimConnector::spawn({"-u", "NONE"});
 33  		c->setParent(this);
 34  		QSignalSpy onReady(c, SIGNAL(ready()));
 35  		QVERIFY(onReady.isValid());
 36  
 37  		QVERIFY(SPYWAIT(onReady));
 38  		QVERIFY(c->isReady());
 39  	}
 40  
 41  	void encodeDecode() {
 42  		NeovimConnector *c = NeovimConnector::spawn({"-u", "NONE"});
 43  		c->setParent(this);
 44  		// This will print a warning, but should succeed
 45  		QString s = "ç日本語";
 46  		QByteArray bytes = c->encode(s);
 47  		QCOMPARE(c->decode(bytes), s);
 48  
 49  		QSignalSpy onReady(c, SIGNAL(ready()));
 50  		QVERIFY(onReady.isValid());
 51  		QVERIFY(SPYWAIT(onReady));
 52  
 53  		bytes = c->encode(s);
 54  		QCOMPARE(c->decode(bytes), s);
 55  
 56  	}
 57  
 58  	void connectToNeovimTCP() {
 59  		NeovimConnector *c = NeovimConnector::connectToNeovim("127.0.0.1:64999");
 60  		c->setParent(this);
 61  		QCOMPARE(c->connectionType(), NeovimConnector::HostConnection);
 62  		QSignalSpy onError(c, SIGNAL(error(NeovimError)));
 63  		QVERIFY(onError.isValid());
 64  
 65  		// Pull Request #612: On MacOS, this test can fail without a long timeout value.
 66  		QVERIFY(SPYWAIT(onError, 120000 /*msec*/));
 67  
 68  		QCOMPARE(c->errorCause(), NeovimConnector::SocketError);
 69  		c->deleteLater();
 70  	}
 71  
 72  	void connectToNeovimSocket() {
 73  		NeovimConnector *c = NeovimConnector::connectToNeovim("NoSuchFile");
 74  		c->setParent(this);
 75  		QCOMPARE(c->connectionType(), NeovimConnector::SocketConnection);
 76  		QSignalSpy onError(c, SIGNAL(error(NeovimError)));
 77  		QVERIFY(onError.isValid());
 78  
 79  		// Test Performance: timeout expected, set value carefully.
 80  		QVERIFY(!SPYWAIT(onError, 5000 /*msec*/));
 81  
 82  		QCOMPARE(c->errorCause(), NeovimConnector::SocketError);
 83  		c->deleteLater();
 84  	}
 85  
 86  	void connectToNeovimEnvEmpty() {
 87  		// This is the same as ::spawn()
 88  		NeovimConnector *c = NeovimConnector::connectToNeovim("");
 89  		c->setParent(this);
 90  		QSignalSpy onReady(c, SIGNAL(ready()));
 91  		QVERIFY(onReady.isValid());
 92  		QVERIFY(SPYWAIT(onReady));
 93  
 94  		c->deleteLater();
 95  	}
 96  
 97  
 98  #ifdef Q_OS_UNIX
 99  	void connectToSocket_data() {
100  		QTest::addColumn<QString>("socketname");
101  
102  		QTest::newRow("relative") << "relnvimsock";
103  		QTest::newRow("./relative") << "./relnvimsock";
104  		QTest::newRow("absolute") << QFileInfo("absnvimsock").absoluteFilePath();
105  	}
106  
107  	// https://github.com/equalsraf/neovim-qt/issues/936
108  	// QLocalSocket cannot open relative paths. This happens
109  	// both in Linux and Mac.
110  	void connectToSocket() {
111  		QFETCH(QString, socketname);
112  
113  		QDir().remove(socketname);
114  		// Start nvim
115  		QProcess p;
116  		p.setProgram("nvim");
117  		QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
118  
119  		auto path_info = QFileInfo(socketname);
120  		if (path_info.isAbsolute()) {
121  			env.insert("NVIM_LISTEN_ADDRESS", socketname);
122  		}
123  		else {
124  			env.insert("NVIM_LISTEN_ADDRESS", "./" + socketname);
125  		}
126  		p.setProcessEnvironment(env);
127  		p.setArguments({"--headless", "-u", "NONE"});
128  		p.start();
129  		p.waitForStarted();
130  
131  		QTest::qWait(1500);
132  		// connect
133  		NeovimConnector *c = NeovimConnector::connectToSocket(socketname);
134  		qDebug() << c->connectionDescription();
135  		QSignalSpy onReady(c, SIGNAL(ready()));
136  		QVERIFY(onReady.isValid());
137  		QVERIFY(SPYWAIT(onReady, 5000 /*msec*/));
138  
139  		QCOMPARE(c->connectionType(), NeovimConnector::SocketConnection);
140  	}
141  #endif
142  
143  	void metadataTimeout() {
144  		// Connect to a TCP socket that will never respond, should trigger
145  		// a timeout for the discoverMetadata call
146  		QTcpServer *server = new QTcpServer();
147  		server->listen(QHostAddress::LocalHost);
148  		QVERIFY(server->isListening());
149  
150  		NeovimConnector* c =
151  			NeovimConnector::connectToNeovim(QStringLiteral("%1:%2")
152  												 .arg(server->serverAddress().toString())
153  												 .arg(server->serverPort()));
154  
155  		// Test Performance: timeout expected, set value carefully.
156  		c->setRequestTimeout(1000 /*msec*/);
157  
158  		QSignalSpy onError(c, SIGNAL(error(NeovimError)));
159  		QVERIFY(onError.isValid());
160  
161  		QVERIFY(SPYWAIT(onError, 5000 /*msec*/));
162  
163  		QCOMPARE(c->errorCause(), NeovimConnector::RuntimeMsgpackError);
164  		c->deleteLater();
165  	}
166  };
167  
168  } // Namespace NeovimQt
169  QTEST_MAIN(NeovimQt::Test)
170  #include "tst_neovimconnector.moc"