"""
smallwp unittest suite helper functions.

import testhelpers before any smallwp modules in test modules and add

if __name__=="__main__":
	testhelpers.main(DefaultTestClass)

at their foot.  

You can obtain a wikipedia data instance by calling testhelpers.getWPData()
or by inheriting from WPDataTest and using the wpData class attribute.

The WPData attribute makes sure some artificial data is used; it is imported
if necessary.  The test data comes from testdata.xml.

All tests must be run from within the tests directory.  The software
must be installed for the tests to run.
"""

import functools
import os
import sys
import traceback
import unittest

os.environ["SMALLWPCONF"] = os.path.join(os.getcwd(), "config-test")

from smallwp import wpprefs

wpprefs.setPref("baseDir", os.path.join(os.getcwd(), "testdata"))

# only import smallwp modules below here

from smallwp import wpdata

def memoized(origFun):
	"""a trivial memoizing decorator.
	"""
	cache = {}
	def fun(*args):
		if args not in cache:
			cache[args] = origFun(*args)
		return cache[args]
	return functools.update_wrapper(fun, origFun)


class TestdataOpts(object):
	lang = "ts"
	inputFormat = "XML"


@memoized
def getWPData():
	try:
		wpd = wpdata.makeData()
		if wpd.getMeta("lang")!=TestdataOpts.lang:
			raise IOError("Bad data")
	except IOError:
		from smallwp import splitstuff
		splitstuff.splitSource("testdata.xml", TestdataOpts)
		wpd = wpdata.makeData()
	return wpd



class WPDataTest(unittest.TestCase):
	wpData = getWPData()


def main(testClass, methodPrefix=None):
	# two args: first one is class name, locate it in caller's globals
	# and ignore anything before any dot for cut'n'paste convenience
	if len(sys.argv)>2:
		className = sys.argv[-2].split(".")[-1]
		testClass = getattr(sys.modules["__main__"], className)
	
	# one arg: test method prefix on testClass
	if len(sys.argv)>1:
		suite = unittest.makeSuite(testClass, methodPrefix or sys.argv[-1],
			suiteClass=unittest.TestSuite)
	else:  # Zero args, emulate unittest.run behaviour
		suite = unittest.TestLoader().loadTestsFromModule(
			sys.modules["__main__"])

	try:
		runner = unittest.TextTestRunner()
		runner.run(suite)
	except (SystemExit, KeyboardInterrupt):
		raise
