"""
#-------------------------------------------------------------------------------
# Name:        arcapi_test
# Purpose:     Tests for arcapi module.
#
# Author:      Filip Kral, Caleb Mackay
#
# Created:     01/02/2014
# Updated:     05/15/2014
# Licence:     LGPL v3
#-------------------------------------------------------------------------------
# Most of the functions operate on potentially complex data, or require manual
# checking of results, and therefore testing is rather difficult.
#
# Everybody is encouraged to contribute to tests.
#-------------------------------------------------------------------------------
"""

import unittest
import os
import sys
import arcpy
import arcapi as ap


class TestGlobalFunctions(unittest.TestCase):

    def setUp(self):
        # access testing data
        try:
            self.testingfolder = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testing')
        except:
            self.testingfolder = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'testing')
        self.testing_gdb = os.path.join(self.testingfolder, 'testing.gdb')
        #self.t_table = os.path.join(self.testing_gdb, '\left_i_right')
        #self.t_fc =  os.path.join(self.testing_gdb, 'left_i_right')
        #self.t_cols = ('OBJECTID', 'Shape', 'CCARM2', 'POINT_X', u'POINT_Y', u'ROUND_X', 'ROUND_Y', 'name', 'propagatedName', 'fullName', 'GID', 'DOWNGID', 'HA_NUM','STRAHLER', 'SHREVE', 'OS_NAME', 'FNODE_FULL', 'TNODE_FULL', 'NAMENOXML', 'Shape_Length')
        self.t_fc =  os.path.join(self.testing_gdb, 'ne_110m_admin_0_countries')
        self.t_fc2 = os.path.join(self.testing_gdb, 'Illinois')
        self.t_tab = os.path.join(self.testing_gdb, 'Illinois_county_info')
        self.t_cols =  ('OBJECTID','Shape','ScaleRank','LabelRank','FeatureCla',
                      'SOVEREIGNT','SOV_A3','ADM0_DIF','LEVEL','TYPE','ADMIN',
                      'ADM0_A3','GEOU_DIF','GEOUNIT','GU_A3','SU_DIF','SUBUNIT',
                      'SU_A3','NAME','ABBREV','POSTAL','NAME_FORMA','TERR_',
                      'NAME_SORT','MAP_COLOR','POP_EST','GDP_MD_EST','FIPS_10_',
                      'ISO_A2','ISO_A3','ISO_N3','Shape_Length','Shape_Area')
        pass

    def tearDown(self):
        pass

    def testnames(self):
        est = map(str, tuple(ap.names(self.t_fc)))
        obs = ('OBJECTID','Shape','ScaleRank','LabelRank','FeatureCla',
                'SOVEREIGNT','SOV_A3','ADM0_DIF','LEVEL','TYPE','ADMIN',
                'ADM0_A3','GEOU_DIF','GEOUNIT','GU_A3','SU_DIF','SUBUNIT',
                'SU_A3','NAME','ABBREV','POSTAL','NAME_FORMA','TERR_',
                'NAME_SORT','MAP_COLOR','POP_EST','GDP_MD_EST','FIPS_10_',
                'ISO_A2','ISO_A3','ISO_N3','Shape_Length','Shape_Area')
        self.assertEqual(tuple(est), obs)
        pass

    def testtypes(self):
        est = map(str, tuple(ap.types(self.t_fc)))
        obs = ('OID','Geometry','SmallInteger','SmallInteger','String','String',
                'String','Single','Single','String','String','String','Single',
                'String', 'String','Single','String','String','String','String',
                'String','String', 'String','String','Single','Double','Double',
                'Single','String','String', 'Single','Double','Double')
        pass

    def testnrow(self):
        est = ap.nrow(self.t_fc)
        obs = 177
        self.assertEqual(est, obs)
        pass

    def testvalues(self):

        fc = self.t_fc
        w = '"OBJECTID" < 11'

        vals1 = ap.values(fc, 'Shape_Length', w)
        vals2 = ap.values(fc, 'Shape_Length', w, 'Shape_Length ASC')
        vals3 = ap.values(fc, 'SHAPE@XY', w)
        vals4 = ap.values(fc, 'SHAPE@XY;Shape_Length', w, 'Shape_Length DESC')
        vals5 = ap.values(fc, 'OBJECTID')[0:10]
        est = all([len(vi) == 10 for vi in [vals1, vals2, vals3, vals4, vals5]])
        self.assertTrue(est)

    def testvalues_crosscolumns(self):
        # the values function requires columns included in the o parameter
        # to be included in the col parameter too, otherwise an invalid
        # sql statement is generated.
        fc = self.t_fc
        w = '"OBJECTID" < 11'
        with self.assertRaises(RuntimeError):
            vals = ap.values(fc, 'SHAPE@XY', w, 'Shape_Length ASC')
        pass


##    def testdistinct(self):
##        pass

    def testhead(self):
        est = 5
        hd = ap.head(self.t_fc, est, geoms = " ", verbose=False)
        obs = len(hd[0])
        self.assertEqual(est, obs)
        pass

    def testchart(self):
        obs = r'c:\temp\chart.jpg'
        t_fc = self.t_fc
        est = ap.chart(t_fc, obs, texts = {'txt': 'Element txt'}, openit=False)
        self.assertEqual(str(est).lower(), str(obs).lower())
        pass

    def testplot(self):
        pic = r'c:\temp\plot.png'
        x = xrange(20)
        ap.plot(x, out_file=pic, openit=False)
        y = xrange(50,70)
        ap.plot(x, y, pic, 'Main', 'X [m]', 'Y [m]', 'o', 'k', openit=False)
        os.remove(pic)
        with self.assertRaises(ap.ArcapiError):
            ap.plot(x, [1,2,3], pic, 'Main', 'X [m]', 'Y [m]', 'o', 'k', openit=False)
        pass

    def testhist(self):
        pic = r'c:\temp\plot.png'
        x = xrange(20)
        h = ap.hist(x, out_file=pic, openit=False)
        h = ap.hist(x, pic, main='Main', xlab='Xlbl', log=True, openit=False)
        os.remove(pic)
        self.assertFalse(os.path.exists(pic))

    def testbars(self):
        pic = r'c:\temp\plot.png'
        x = xrange(20)
        ap.bars(x, out_file=pic, openit=False)
        y = xrange(50,70)
        ap.bars(x, out_file=pic, labels=y, main='Main', xlab='X', ylab='Y', openit=False)
        ap.bars([], openit=False)
        os.remove(pic)
        self.assertFalse(os.path.exists(pic))

    def testpie(self):
        pic = r'c:\temp\plot.png'
        x = [1,2,3,4,5,6,7]
        y = [1,1,2,2,3,3,3]
        ap.pie(x, openit=False)
        ap.pie(x, y, main="A chart", out_file=pic, autopct='%1.1f%%', openit=False)
        ap.pie(x=[], y=[], openit=False)
        os.remove(pic)
        self.assertFalse(os.path.exists(pic))

    def testrename_col(self):
        import arcpy
        import tempfile
        owo = arcpy.env.overwriteOutput
        arcpy.env.overwriteOutput = True
        tmpfc = os.path.join(tempfile.gettempdir(), "tmp")
        tmpfc = arcpy.CopyFeatures_management(self.t_fc, tmpfc).getOutput(0)
        est = ap.rename_col(tmpfc, "ABBREV", "ABBREVIATION")
        obs = "ABBREVIATI"
        arcpy.Delete_management(tmpfc)
        arcpy.env.overwriteOutput = owo
        self.assertEqual(est, obs)
        pass

    def testtlist_to_table(self):
        colnames = ['NAME', 'POP_EST']
        coltypes = ['TEXT', 'DOUBLE']
        collengths = [250, '#']
        coldefs = zip(colnames, coltypes, collengths)
        coldefs2 = ['NAME:TEXT', 'POP_EST:DOUBLE']

        # read data
        tl = []
        with arcpy.da.SearchCursor(self.t_fc, colnames) as sc:
            for row in sc:
                tl.append(tuple(row))

        # write as table using log column definition
        ot = arcpy.CreateScratchName('tmp.dbf', workspace='c:\\temp')
        ot = ap.tlist_to_table(tl, ot, coldefs, -9, 'nullText')
        est1 = int(arcpy.GetCount_management(ot).getOutput(0))

        # write as table using short column definition
        ot = arcpy.CreateScratchName('tmp.dbf', workspace='c:\\temp')
        ot = ap.tlist_to_table(tl, ot, coldefs2, -9, 'nullText')
        est2 = int(arcpy.GetCount_management(ot).getOutput(0))
        obs = int(arcpy.GetCount_management(self.t_fc).getOutput(0))

        arcpy.Delete_management(ot)
        self.assertTrue(all((est1 == obs, est2 == obs)))
        pass

##    def testdocu(self):
##        pass

    def testmeta(self):
        fcws = 'c:\\temp'
        tempshp = arcpy.CreateScratchName('tmp.dbf', workspace=fcws).replace('.dbf', '.shp')
        fcnm = os.path.basename(tempshp)

        # testing entries
        ttl,pps,abt = "Bar","example", "Column Spam means eggs"

        fc = arcpy.FeatureClassToFeatureClass_conversion(
            self.t_fc,
            fcws,
            fcnm
        ).getOutput(0)
        ap.meta(fc, 'OVERWRITE', title=ttl)
        editted = ap.meta(fc, 'append', purpose=pps, abstract=abt)
        editted = ap.meta(fc, 'overwrite', title=ttl, purpose=pps, abstract=abt)
        retrieved = ap.meta(fc)
        ap.dlt(fc)
        self.assertEqual(set(editted.values()), set(retrieved.values()))

##    def testmsg(self):
##        pass

    def testfrequency(self):
        est = ap.frequency([1,1,2,3,4,4,4])
        obs = {1: 2, 2: 1, 3: 1, 4: 3}
        samekeys = set(est.keys()) == set(obs.keys())
        good = all([samekeys] + [est[i] == obs[i] for i in est])
        self.assertTrue(good)
        pass

    def testlist_environments(self):
        envs = ap.list_environments([])
        self.assertEqual(len(envs), 50)
        pass

    def testoidF(self):
        est = ap.oidF(self.t_fc)
        obs = "OBJECTID"
        self.assertEqual(str(est), obs)
        pass

    def testshpF(self):
        est = ap.shpF(self.t_fc)
        obs = "Shape"
        self.assertEqual(str(est), obs)
        pass

    def testtstamp(self):
        est = []
        est.append(len(ap.tstamp()) == len('20140216184029'))
        est.append(len(ap.tstamp("lr")) == len('lr20140216184045'))
        est.append(len(ap.tstamp("lr", "%H%M%S")) == len('lr184045'))
        est.append(len(ap.tstamp("lr", "%H%M%S")) == len('lr184045'))
        est.append(len(ap.tstamp("lr", "%H%M%S", s=('run',1))) == len('lr184527_run_1'))
        obs = [True, True, True, True, True]
        self.assertEqual(est, obs)
        pass

    def testdlt(self):
        est = []
        wc = '"OBJECTID" < 11'
        lr = arcpy.management.MakeFeatureLayer(self.t_fc, "lr", wc).getOutput(0)
        # TODO: test for deleting layers won't pass even though ap.dlt works
        #print lr
        #print arcpy.Exists(lr)
        tempfc = 'in_memory\\tmp'
        if arcpy.Exists(tempfc):
            arcpy.Delete_management(tempfc)
        tmpfc = arcpy.CopyFeatures_management(lr, tempfc).getOutput(0)
        tempshp = arcpy.CreateScratchName('tmp.dbf', workspace='c:\\temp').replace('.dbf', '.shp')
        fc = arcpy.CopyFeatures_management(tmpfc, tempshp).getOutput(0)
        ap.dlt(lr)
        est.append(ap.dlt(tmpfc))
        est.append(ap.dlt(fc))
        est.append(ap.dlt('this does not exist'))
        self.assertEquals(est, [True, True, False])
        pass

    def testcleanup(self):
        x = []
        out = arcpy.CreateScratchName("tmp", workspace=arcpy.env.scratchGDB)
        x.append(arcpy.management.Copy(self.t_fc, out).getOutput(0))
        est = ap.cleanup(x)
        obs = 0
        self.assertEqual(est, obs)

    def testto_points(self):
        obs = 10
        wc = '"OBJECTID" < ' + str(obs + 1)
        ofc = arcpy.CreateScratchName("tmp_out.dbf", workspace="c:\\temp").replace('.dbf', '.shp')
        cs = 27700
        ptfc = ap.to_points(self.t_fc, ofc, "POP_EST", "GDP_MD_EST", cs, w = wc)
        est = int(arcpy.GetCount_management(ptfc).getOutput(0))
        arcpy.Delete_management(ptfc)
        self.assertEqual(est, obs)
        pass


##    def testwsp(self):
##        pass
##
##    def testswsp(self):
##        pass

    def testto_scratch(self):
        est = []
        obs = []
        arcpy.env.scratchWorkspace = arcpy.env.scratchGDB
        s = arcpy.env.scratchWorkspace

        est.append(ap.to_scratch('foo', 0))
        obs.append(ap.os.path.join(s, 'foo'))
        est.append(ap.to_scratch('foo', 1))
        obs.append(os.path.join(s, 'foo0'))
        est.append(ap.to_scratch('foo.shp', 0))
        obs.append(os.path.join(s, 'foo_shp'))
        est.append(ap.to_scratch('foo.shp', 1))
        obs.append(os.path.join(s, 'foo_shp0'))

        # not tested for file based workspaces
        arcpy.env.scratchWorkspace = arcpy.env.scratchFolder
        a = arcpy.env.scratchWorkspace
        ap.to_scratch('foo', 0) == os.path.join(s, 'foo')
        ap.to_scratch('foo', 1) == os.path.join(s, 'foo0')
        ap.to_scratch('foo.shp', 0) == os.path.join(s, 'foo_shp')
        ap.to_scratch('foo.shp', 1) == os.path.join(s, 'foo_shp0')

        eq = all([ei == oi for ei,oi in zip(est, obs)])
        self.assertTrue(eq)

    def testremap_sa(self):
        est = []

        remapped = ap.remap_3d(10,50,10)
        est.append(remapped == '10 20 1;20 30 2;30 40 3;40 50 4')

        remapped = ap.remap_3d(0,5,1)
        est.append(remapped == '0 1 1;1 2 2;2 3 3;3 4 4;4 5 5')

        remapped = ap.remap_3d(-10,10,5)
        est.append(remapped == '-10 -5 1;-5 0 2;0 5 3;5 10 4')

        remapped = ap.remap_3d(-10,10,-5)
        est.append(remapped == '')

        remapped = ap.remap_3d(10,-20,-7)
        est.append(remapped == '10 3 1;3 -4 2;-4 -11 3;-11 -18 4;-18 -25 5')

        self.assertTrue(all(est))

    def testremap_3d(self):
        est = []

        remapped = ap.remap_sa(10,50,10)
        ob = [[[10, 20], 1], [[20, 30], 2], [[30, 40], 3], [[40, 50], 4]]
        est.append(remapped == ob)

        remapped = ap.remap_sa(0,5,1)
        ob = [[[0, 1], 1], [[1, 2], 2], [[2, 3], 3], [[3, 4], 4], [[4, 5], 5]]
        est.append(remapped == ob)

        remapped = ap.remap_sa(-10,10,5)
        ob = [[[-10, -5], 1], [[-5, 0], 2], [[0, 5], 3], [[5, 10], 4]]
        est.append(remapped == ob)

        remapped = ap.remap_sa(-10,10,-5)
        ob = []
        est.append(remapped == ob)

        remapped = ap.remap_sa(10,-20,-7)
        ob = [
            [[10, 3], 1], [[3, -4], 2], [[-4, -11], 3], [[-11, -18], 4],
            [[-18, -25], 5]
        ]
        est.append(remapped == ob)

        self.assertTrue(all(est))

    def testfind(self):
        self.testingfolder = os.path.join(os.path.dirname(sys.argv[0]), 'testing')
        obs = [1, 5]
        est = []
        findings = ap.find('*.shp', self.testingfolder)
        est.append(len(findings))
        findings = ap.find('*110m*', self.testingfolder)
        est.append(len(findings))
        self.assertEqual(est, obs)

    def testfixArgs(self):
        list_args = 'C:\Temp\Shapefiles\Contours.shp;C:\Temp\Shapefiles\Contours.shp'
        est = ap.fixArgs(list_args, list)
        obs = ['C:\\Temp\\Shapefiles\\Contours.shp', 'C:\\Temp\\Shapefiles\\Contours.shp']
        self.assertEqual(est, obs)
        est = ap.fixArgs('false', bool)
        self.assertEqual(est, False)
        pass

    def testint_to_float(self):
        _dir = os.path.join(self.testingfolder, r'testing_files\rasters')
        ndvi = os.path.join(_dir, 'dh_july_ndvi')
        ob = round(arcpy.Raster(ndvi).maximum, 5)
        int_rst = os.path.join(_dir, 'ndvi_int')
        est = os.path.join(_dir, 'ndvi_tst')
        if arcpy.CheckExtension('Spatial') == 'Available':
            arcpy.CheckOutExtension('Spatial')
            arcpy.sa.Int(arcpy.sa.Times(ndvi, 1000000)).save(int_rst)
            arcpy.CheckInExtension('Spatial')
            ap.int_to_float(int_rst, est, 6)
            self.assertEqual(ob, round(arcpy.Raster(est).maximum, 5))
            for rast in [int_rst, est]:
                try:
                    arcpy.Delete_management(rast)
                except:pass
        pass

    def testfill_no_data(self):
        _dir = os.path.join(self.testingfolder, r'testing_files\rasters')
        ndvi = os.path.join(_dir, 'dh_july_ndvi')
        est = os.path.join(_dir, 'ndvi_fill')
        null = os.path.join(_dir, 'null_rst')
        if arcpy.CheckExtension('Spatial') == 'Available':
            ap.fill_no_data(ndvi, est, 10, 10)
            arcpy.CheckOutExtension('Spatial')
            arcpy.sa.IsNull(est).save(null)
            self.assertEqual(arcpy.Raster(null).maximum, 0)
            arcpy.CheckInExtension('Spatial')
            for rast in [est, null]:
                try:
                    arcpy.Delete_management(rast)
                except:pass
        pass

    def testmeters_to_feet(self):
        _dir = os.path.join(self.testingfolder, r'testing_files\rasters')
        dem = os.path.join(_dir, 'dh30m_dem')
        est = os.path.join(_dir, 'dem_ft')
        ap.meters_to_feet(dem, est)
        self.assertEqual(int(arcpy.Raster(est).maximum), 6244)
        try:
            arcpy.Delete_management(est)
        except:
            pass
        pass

    def testcopy_schema(self):
        tmp = r'in_memory\schema_test'
        ap.copy_schema(self.t_fc, tmp)
        self.assertTrue(arcpy.Exists(tmp))
        arcpy.Delete_management(tmp)
        pass

    def testmake_poly_from_extent(self):
        desc = arcpy.Describe(self.t_fc2)
        ext = desc.extent
        sr = desc.spatialReference
        est = ap.make_poly_from_extent(ext, sr)
        self.assertEqual(str(ext), str(est.extent))
        pass

    def testlist_all_fcs(self):
        est = ap.list_all_fcs(self.testing_gdb, '*', 'All', True)
        obs = ['Illinois', 'ne_110m_admin_0_countries']
        self.assertEqual(est, obs)
        pass

    def testfield_list(self):
        il = os.path.join(self.testing_gdb, 'Illinois')
        est = ap.field_list(il, ['state_fips', 'cnty_fips'])
        obs = ['OBJECTID', 'Shape', 'NAME', 'STATE_NAME',
               'FIPS', 'Shape_Length', 'Shape_Area']
        self.assertEqual(est, obs)
        pass

    def testget_field_type(self):
        il = os.path.join(self.testing_gdb, 'Illinois')
        est = ap.get_field_type('NAME', il)
        self.assertEqual(est, 'TEXT')
        pass

    def testmatch_field(self):
        fc = os.path.join(self.testing_gdb, 'Illinois')
        est = ap.match_field(fc, '*fips', True)
        obs = ['STATE_FIPS', 'CNTY_FIPS', 'FIPS']
        self.assertEqual(est, obs)
        pass

    def testadd_fields_from_table(self):
        fc = os.path.join(self.testing_gdb, 'Illinois')
        copy = fc + '_copy'
        if arcpy.Exists(copy):
            arcpy.Delete_management(copy)
        arcpy.CopyFeatures_management(fc, copy)
        flds = ['POP1990', 'POP2000']
        tab = fc = os.path.join(self.testing_gdb, 'Illinois_county_info')
        ap.add_fields_from_table(copy, tab, flds)
        est = [f.name for f in arcpy.ListFields(copy)]
        try:
            arcpy.Delete_management(copy)
        except: pass
        for f in flds:
            self.assertTrue(f in est)
        pass

    def testcreate_field_name(self):
        fc = os.path.join(self.testing_gdb, 'Illinois')
        est = ap.create_field_name(fc, 'NAME')
        self.assertEqual(est, 'NAME_1')
        pass

    def testjoin_using_dict(self):
        if arcpy.Exists(r'in_memory\copy'):
            arcpy.Delete_management(r'in_memory\copy')
        fc = os.path.join(self.testing_gdb, 'Illinois')
        copy = fc + '_copy'
        if arcpy.Exists(copy):
            arcpy.Delete_management(copy)
        arcpy.CopyFeatures_management(fc, copy)
        flds = ['POP1990', 'POP2000']
        tab = fc = os.path.join(self.testing_gdb, 'Illinois_county_info')
        ap.join_using_dict(copy, 'CNTY_FIPS', tab, 'CNTY_FIPS', flds)
        est = [f.name for f in arcpy.ListFields(copy)]
        try:
            arcpy.Delete_management(copy)
        except: pass
        for f in flds:
            self.assertTrue(f in est)
        pass

    def testconcatenate(self):
        est = ap.concatenate(['A','B','C'], '-')
        self.assertEqual(est, 'A-B-C')
        pass

    def testconcatenate_fields(self):
        if arcpy.Exists(r'in_memory\copy'):
            arcpy.Delete_management(r'in_memory\copy')
        fc = os.path.join(self.testing_gdb, 'Illinois')
        copy = fc + '_copy'
        if arcpy.Exists(copy):
            arcpy.Delete_management(copy)
        arcpy.CopyFeatures_management(fc, copy)
        ap.concatenate_fields(copy, 'FULL', 75, ['NAME', 'STATE_NAME'], ' County, ')
        obs = 'Jo Daviess County, Illinois'
        with arcpy.da.SearchCursor(copy, 'FULL') as rows:
            est = rows.next()[0]
        del rows
        try:
            arcpy.Delete_management(copy)
        except: pass
        self.assertEqual(est, obs)
        pass

    def testcreate_pie_chart(self):
        tab = fc = os.path.join(self.testing_gdb, 'Illinois_county_info')
        oid = arcpy.AddFieldDelimiters(tab, arcpy.Describe(tab).OIDFieldName)
        where = '{0} < 11'.format(oid)
        tv = arcpy.MakeTableView_management(tab, 'IL_table', where)
        fig = os.path.join(self.testingfolder, 'IL_county_pop.png')
        # will use 'CNTY_FIPS' as case field since our pop field is
        # already populated for each county
        ap.create_pie_chart(fig, tv, 'NAME','POP2000', 'IL Counties')
        self.assertTrue(os.path.exists(fig))
####        try:
####            arcpy.Delete_management(fig) # may want to look at the figure, pretty cool!
####        except:
####            pass
        pass

    def testcombine_pdfs(self):
        _dir = os.path.dirname(self.testingfolder)
        mapDoc = os.path.join(_dir, 'chart.mxd')
        mxd = arcpy.mapping.MapDocument(mapDoc)
        txt_elm = [elm for elm in arcpy.mapping.ListLayoutElements(mxd, 'TEXT_ELEMENT')
                   if elm.text == 'SomeText'][0]
        del_list = []
        for i in range(3):
            txt_elm.text = "Hi, I'm page {0}".format(i)
            pdf = os.path.join(_dir, 'test_{0}.pdf'.format(i))
            arcpy.mapping.ExportToPDF(mxd, pdf, resolution=100)
            del_list.append(pdf)
        combined = os.path.join(_dir, 'combined.pdf')
        del mxd
        ap.combine_pdfs(combined, del_list)
        self.assertTrue(os.path.exists(combined))
        del_list.append(combined)
        try:
            for p in del_list:
                arcpy.Delete_management(p)
        except:
            pass
        pass

    def testlist_data(self):
        """TODO: Write more tests for listing data"""
        expected = ['testing.gdb','testing_files']
        data = ap.list_data(self.testingfolder)
        datas = str("".join(data))
        all_in = all([(ei in datas) for ei in expected])
        self.assertTrue(all_in)

    def testrequest_text(self):
        """Basic test to get a page as text"""
        d = ap.request('http://google.com')
        self.assertNotEqual(d, '')

    def testrequest_json(self):
        """Get json from arcgis sampleserver"""
        u = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services'
        d = ap.request(u, {'f':'json'}, 'json')
        items = [
            isinstance(d, dict),
            isinstance(d.get('services'), list),
            isinstance(d.get('folders'), list),
            isinstance(d.get('currentVersion'), int)
        ]
        self.assertTrue(all(items))

    def testrequest_xml(self):
        """Get XML from epsg.io"""
        u = 'http://epsg.io/4326.xml'
        d = ap.request(u, None, 'xml')

        tg = str(d.tag)
        tp = '{http://www.opengis.net/gml/3.2}GeographicCRS'

        self.assertEqual(tg, tp)

    def testarctype_to_ptype(self):
        """Converting from ArcGIS type strings to python types"""
        self.assertTrue(ap.arctype_to_ptype("SHORT") is int)
        self.assertTrue(ap.arctype_to_ptype("Short") is int)
        self.assertTrue(ap.arctype_to_ptype("SHORT ") is int)
        self.assertTrue(ap.arctype_to_ptype("TEXT") is str)
        self.assertTrue(ap.arctype_to_ptype("STRING") is str)

        self.assertTrue(ap.arctype_to_ptype("SMALLINTEGER") is int)
        self.assertTrue(ap.arctype_to_ptype("LONG") is int)
        self.assertTrue(ap.arctype_to_ptype("INTEGER") is int)
        self.assertTrue(ap.arctype_to_ptype("DATE") is datetime.datetime)
        self.assertTrue(ap.arctype_to_ptype("DATETIME") is datetime.datetime)
        self.assertTrue(ap.arctype_to_ptype("FLOAT") is float)
        self.assertTrue(ap.arctype_to_ptype("SINGLE") is float)
        self.assertTrue(ap.arctype_to_ptype("DOUBLE") is float)

        self.assertTrue(ap.arctype_to_ptype("") is str)
        self.assertTrue(ap.arctype_to_ptype(None) is str)

        with self.assertRaises(Exception):
            ap.arctype_to_ptype()
        pass

    def testproject_coordinates(self):
        """Projecting list of coordinate pairs"""
        dtt = 'TM65_To_WGS_1984_2 + OSGB_1936_To_WGS_1984_NGA_7PAR'
        coordinates = [(240600.0, 375800.0), (245900.0, 372200.0)]
        observed = ap.project_coordinates(coordinates, 29902, 27700, dtt)
        expected = [
            (53444.10991363949, 539226.5651404626),
            (58422.59724314464, 535183.1931399861)
        ]
        self.assertEqual(observed, expected)
        pass


if __name__ == '__main__':
    unittest.main(verbosity = 2)