import os
import sys
import unittest
import doctest
import fnmatch
import imp

# based on http://code.activestate.com/recipes/474083/
# get the absolute path of [:x]'s parents up from this script location
# as this script should be in gluon/tests we are looking for gluon (up 1)
gluon_path = reduce (lambda l, r:
    l + os.path.sep + r,
    os.path.dirname(os.path.realpath(__file__)).split(os.path.sep)[:-1])
sys.path.append(gluon_path)

# some scripts require that we work from web2py's root (up 1)
os.chdir(os.path.join(gluon_path, '..'))

# list any subdirs of gluon here that must be excluded
exclude_subdirs = ['scripts', 'tests']
# and the same for specific modules
exclude_modules = [
    'memcache',     # requires memcache(d)
    'memdb',        # depends on google app engine, tb updated
    ]

# make full paths
excluded_paths = \
    [os.path.join(gluon_path, subdir) for subdir in exclude_subdirs]

# build a suite of doctests
suite = unittest.TestSuite()
has_no_doctests = {}

print '--collecting--'
for path, subdirs, files in os.walk(gluon_path):
    if path in excluded_paths:
        continue
    for mod_file in [filename for filename in files
                            if fnmatch.fnmatch(filename, '*.py')]:
        mod_name = mod_file[:-3]    # skip '.py'
        if mod_name in exclude_modules:
            continue
        (f, filename, description) = imp.find_module(mod_name, [path])
        try:
            mod = imp.load_module(mod_name, f, filename, description)
            suite.addTest(doctest.DocTestSuite(mod))
        except ValueError, e:
            # so far, only for missing doctests
            has_no_doctests[os.path.join(path, mod_file)[len(gluon_path):]] = e
        except ImportError, e:
            # we can encounter some modules not being present
            print '%s: %s' % (os.path.join(path, mod_file)[len(gluon_path):], e)
        finally:
            if f:
                f.close()

print '---no doctests--'
for mod in has_no_doctests.keys():
    print '%s: %s' % (mod, has_no_doctests[mod])

print '--running doctests--'
runner = unittest.TextTestRunner()
runner.run(suite)
