"""
A regression test for the sync TAP client and the server.

We use the unittest framework, but the tests themselves are, admittedly,
no unit tests; also, the idea is to primarily exercise the remote
server.

To run this, you need the GAVO votable library.
"""

import datetime
import re
import sys
import time
import unittest
import urllib
from cStringIO import StringIO

from gavo import votable
from gavo.votable import tapquery


ENDPOINT_URL = "http://localhost:8080/tap"
#ENDPOINT_URL = "http://dc.zah.uni-heidelberg.de/tap"


class ADQLJobTest(unittest.TestCase):
	def getJob(self, query, parameters={}):
		return votable.ADQLSyncJob(
			ENDPOINT_URL, query, userParams=parameters)
	
	def assertRaisesWithMessage(self, exClass, msgPat, callable, *args, **kwargs):
		try:
			callable(*args, **kwargs)
		except exClass, ex:
			if not re.match(msgPat, str(ex)):
				raise self.failureException(
					"Expected %r, got %r as exception message"%(msgPat, str(ex)))
		except:
			raise
		else:
			raise self.failureException("%s not raised"%exClass)


class SimpleSyncTest(ADQLJobTest):
	def testPlainQuery(self):
		data, metadata = votable.load(self.getJob(
			"SELECT * FROM taptest.main where spectral='K3j'"
		).start().openResult())
		self.assertEqual(len(data), 2)
	
	def testWrongEndpoint(self):
		job = votable.ADQLSyncJob(ENDPOINT_URL+"quatch", "foobar")
		self.assertRaises(tapquery.WrongStatus, job.start)

	def testHTTPError(self):
		job = votable.ADQLSyncJob("http://192.168.203.156/notap", "hukx",
			timeout=0.01)
		self.assertRaises(tapquery.NetworkError, job.start)

	def testParameterCons(self):
		job = self.getJob("SELECT * FROM taptest.main", parameters={"MAXREC": 1})
		data, metadata = votable.load(job.start().openResult())
		self.assertEqual(len(data), 1)

	def testParameterLater(self):
		job = self.getJob("SELECT * FROM taptest.main")
		job.setParameter("MAXREC", "1")
		data, metadata = votable.load(job.start().openResult())
		self.assertEqual(len(data), 1)

	def testParsedError(self):
		job = self.getJob("SLECT * FROM taptest.main")
		self.assertRaises(tapquery.WrongStatus, job.start)
		self.assertEqual(job.getErrorFromServer(),
			'Could not parse your query: Expected "SELECT" (at char 0),'
			' (line:1, col:1)')



def main():
	methodPrefix = "test"
	if len(sys.argv)==3:
		methodPrefix = sys.argv[2]
	if 2<=len(sys.argv)<=3:
		testClass = globals()[sys.argv[1]]
		suite = unittest.makeSuite(testClass, methodPrefix)
		runner = unittest.TextTestRunner()
		runner.run(suite)
	else:
		unittest.main()


if __name__=="__main__":
	main()
