text: # Project:  MapServer
  # Purpose:  xUnit style Python mapscript tests of Map
  # Author:   Sean Gillies, sgillies@frii.com
  #
  # ===========================================================================
  # Copyright (c) 2004, Sean Gillies
  #
  # Permission is hereby granted, free of charge, to any person obtaining a
  # copy of this software and associated documentation files (the "Software"),
  # to deal in the Software without restriction, including without limitation
  # the rights to use, copy, modify, merge, publish, distribute, sublicense,
  # and/or sell copies of the Software, and to permit persons to whom the
  # Software is furnished to do so, subject to the following conditions:
  #
  # The above copyright notice and this permission notice shall be included
  # in all copies or substantial portions of the Software.
  #
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  # DEALINGS IN THE SOFTWARE.
  # ===========================================================================
  
  import unittest
  import mapscript
  from .testing import MapTestCase, TESTMAPFILE
  
  
  class MapConstructorTestCase(unittest.TestCase):
  
      def testMapConstructorNoArg(self):
          """MapConstructorTestCase.testMapConstructorNoArg: test map constructor with no argument"""
          test_map = mapscript.mapObj()
          assert test_map.__class__.__name__ == "mapObj"
          assert test_map.thisown == 1
  
      def testMapConstructorEmptyStringArg(self):
          """MapConstructorTestCase.testMapConstructorEmptyStringArg:
          test map constructor with old-style empty string argument"""
          test_map = mapscript.mapObj('')
          assert test_map.__class__.__name__ == "mapObj"
          assert test_map.thisown == 1
  
      def testMapConstructorFilenameArg(self):
          """MapConstructorTestCasetest.testMapConstructorEmptyStringArg: map constructor with filename argument"""
          test_map = mapscript.mapObj(TESTMAPFILE)
          assert test_map.__class__.__name__ == "mapObj"
          assert test_map.thisown == 1
  
  
  class MapExtentTestCase(MapTestCase):
      def testSetExtent(self):
          """MapExtentTestCase.testSetExtent: test the setting of a mapObj's extent"""
          test_map = mapscript.mapObj(TESTMAPFILE)
          e = test_map.extent
          result = test_map.setExtent(e.minx, e.miny, e.maxx, e.maxy)
          self.assertAlmostEqual(test_map.scaledenom, 14.24445829)
          assert result == mapscript.MS_SUCCESS, result
  
      def testSetExtentBadly(self):
          """MapExtentTestCase.testSetExtentBadly: test that mapscript raises an error for an invalid mapObj extent"""
          test_map = mapscript.mapObj(TESTMAPFILE)
          self.assertRaises(mapscript.MapServerError, test_map.setExtent,
                            1.0, -2.0, -3.0, 4.0)
  
      def testReBindingExtent(self):
          """test the rebinding of a map's extent"""
          test_map = mapscript.mapObj(TESTMAPFILE)
          rect1 = mapscript.rectObj(-10.0, -10.0, 10.0, 10.0)
          rect2 = mapscript.rectObj(-10.0, -10.0, 10.0, 10.0)
          test_map.extent = rect1
          assert repr(test_map.extent) != repr(rect1), (test_map.extent, rect1)
          del rect1
          self.assertRectsEqual(test_map.extent, rect2)
  
  
  class MapLayersTestCase(MapTestCase):
  
      def testMapInsertLayer(self):
          """MapLayersTestCase.testMapInsertLayer: test insertion of a new layer at default (last) index"""
          n = self.map.numlayers
          layer = mapscript.layerObj()
          layer.name = 'new'
          assert layer.map is None, layer.map
          index = self.map.insertLayer(layer)
          assert layer.map is not None, layer.map
          assert index == n, index
          assert self.map.numlayers == n + 1
          names = [self.map.getLayer(i).name for i in range(self.map.numlayers)]
          assert names == ['RASTER', 'POLYGON', 'LINE', 'POINT', 'INLINE',
                           'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT', 'new']
          order = self.map.getLayerOrder()
          assert order == (0, 1, 2, 3, 4, 5, 6, 7), order
  
      def testMapInsertLayerAtZero(self):
          """MapLayersTestCase.testMapInsertLayerAtZero: test insertion of a new layer at first index"""
          n = self.map.numlayers
          layer = mapscript.layerObj()
          layer.name = 'new'
          assert layer.map is None, layer.map
          index = self.map.insertLayer(layer, 0)
          assert layer.map is not None, layer.map
          assert index == 0, index
          assert self.map.numlayers == n + 1
          names = [self.map.getLayer(i).name for i in range(self.map.numlayers)]
          assert names == ['new', 'RASTER', 'POLYGON', 'LINE', 'POINT', 'INLINE',
                           'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT'], names
          order = self.map.getLayerOrder()
          assert order == (0, 1, 2, 3, 4, 5, 6, 7), order
  
      def testMapInsertLayerDrawingOrder(self):
          """MapLayersTestCase.testMapInsertLayerDrawingOrder: test affect of
          insertion of a new layer at index 1 on drawing order"""
          n = self.map.numlayers
          assert n == 7
          # reverse layer drawing order
          o_start = (6, 5, 4, 3, 2, 1, 0)
          self.map.setLayerOrder(o_start)
          # insert Layer
          layer = mapscript.layerObj()
          layer.name = 'new'
          index = self.map.insertLayer(layer, 1)
          assert index == 1, index
          # We expect our new layer to be at index 1 in drawing order as well
          order = self.map.getLayerOrder()
          assert order == (7, 1, 6, 5, 4, 3, 2, 0), order
  
      def testMapInsertLayerBadIndex(self):
          """MapLayersTestCase.testMapInsertLayerBadIndex: expect an exception when index is too large"""
          layer = mapscript.layerObj()
          self.assertRaises(mapscript.MapServerChildError, self.map.insertLayer,
                            layer, 1000)
  
      def testMapInsertNULLLayer(self):
          """expect an exception on attempt to insert a NULL Layer"""
          self.assertRaises(mapscript.MapServerChildError, self.map.insertLayer,
                            None)
  
      def testMapRemoveLayerAtTail(self):
          """removal of highest index (tail) layer"""
          n = self.map.numlayers
          layer = self.map.removeLayer(n-1)
          assert self.map.numlayers == n-1
          assert layer.name == 'INLINE-PIXMAP-PCT'
          assert layer.thisown == 1
          del layer
          order = self.map.getLayerOrder()
          assert order == (0, 1, 2, 3, 4, 5), order
  
      def testMapRemoveLayerAtZero(self):
          """removal of lowest index (0) layer"""
          n = self.map.numlayers
          layer = self.map.removeLayer(0)
          assert self.map.numlayers == n-1
          assert layer.name == 'RASTER'
          order = self.map.getLayerOrder()
          assert order == (0, 1, 2, 3, 4, 5), order
  
      def testMapRemoveLayerDrawingOrder(self):
          """test affect of layer removal on drawing order"""
          n = self.map.numlayers
          # reverse layer drawing order
          o_start = (6, 5, 4, 3, 2, 1, 0)
          self.map.setLayerOrder(o_start)
          layer = self.map.removeLayer(1)
          assert self.map.numlayers == n-1
          assert layer.name == 'POLYGON'
          order = self.map.getLayerOrder()
          assert order == (5, 4, 3, 2, 1, 0), order
          names = [self.map.getLayer(i).name for i in range(self.map.numlayers)]
          assert names == ['RASTER', 'LINE', 'POINT', 'INLINE',
                           'INLINE-PIXMAP-RGBA', 'INLINE-PIXMAP-PCT'], names
  
  
  class MapExceptionTestCase(MapTestCase):
  
      def testDrawBadData(self):
          """MapExceptionTestCase.testDrawBadData: a bad data descriptor in a layer returns proper error"""
          self.map.getLayerByName('POLYGON').data = 'foo'
          self.assertRaises(mapscript.MapServerError, self.map.draw)
  
  
  class EmptyMapExceptionTestCase(unittest.TestCase):
  
      def setUp(self):
          self.map = mapscript.mapObj('')
  
      def tearDown(self):
          self.map = None
  
      def testDrawEmptyMap(self):
          """EmptyMapExceptionTestCase.testDrawEmptyMap: drawing an empty map returns proper error"""
          self.assertRaises(mapscript.MapServerError, self.map.draw)
  
  
  class MapMetaDataTestCase(MapTestCase):
  
      def testInvalidKeyAccess(self):
          """MapMetaDataTestCase.testInvalidKeyAccess: an invalid map metadata key returns proper error"""
          self.assertRaises(mapscript.MapServerError, self.map.getMetaData, 'foo')
  
      def testFirstKeyAccess(self):
          """MapMetaDataTestCase.testFirstKeyAccess: first metadata key is correct value"""
          key = self.map.getFirstMetaDataKey()
          assert key == 'key1'
          val = self.map.getMetaData(key)
          assert val == 'value1'
  
      def testLastKeyAccess(self):
          """MapMetaDataTestCase.testLastKeyAccess: last metadata key is correct value"""
          key = self.map.getFirstMetaDataKey()
          for i in range(4):
              key = self.map.getNextMetaDataKey(key)
              assert key is not None
          key = self.map.getNextMetaDataKey(key)
          assert key is None
  
      def testMapMetaData(self):
          """MapMetaDataTestCase.testMapMetaData: map metadata keys are correct values"""
          keys = []
          key = self.map.getFirstMetaDataKey()
          if key is not None:
              keys.append(key)
          while 1:
              key = self.map.getNextMetaDataKey(key)
              if not key:
                  break
              keys.append(key)
          assert keys == ['key1', 'key2', 'key3', 'key4', 'ows_enable_request'], keys
  
      def testLayerMetaData(self):
          """MapMetaDataTestCase.testLayerMetaData: layer metadata keys are correct values"""
          keys = []
          key = self.map.getLayer(1).getFirstMetaDataKey()
          if key is not None:
              keys.append(key)
          while 1:
              key = self.map.getLayer(1).getNextMetaDataKey(key)
              if not key:
                  break
              keys.append(key)
          assert keys == ['key1', 'key2', 'key3', 'key4'], keys
  
      def testClassMetaData(self):
          """MapMetaDataTestCase.testClassMetaData: class metadata keys are correct values"""
          keys = []
          key = self.map.getLayer(1).getClass(0).getFirstMetaDataKey()
          if key is not None:
              keys.append(key)
          while 1:
              key = self.map.getLayer(1).getClass(0).getNextMetaDataKey(key)
              if not key:
                  break
              keys.append(key)
          assert keys == ['key1', 'key2', 'key3', 'key4'], keys
  
  
  class NoFontSetTestCase(unittest.TestCase):
  
      def testNoGetFontSetFile(self):
          """an empty map should have fontset filename == None"""
          self.map = mapscript.mapObj()
          assert self.map.fontset.filename is None
  
  
  class MapFontSetTestCase(MapTestCase):
  
      def testGetFontSetFile(self):
          """expect fontset file to be 'fonts.txt'"""
          file = self.map.fontset.filename
          assert file == 'fonts.txt', file
  
  
  class MapSizeTestCase(MapTestCase):
  
      def testDefaultSize(self):
          assert self.map.width == 200
          assert self.map.height == 200
  
      def testSetSize(self):
          retval = self.map.setSize(480, 480)
          assert retval == mapscript.MS_SUCCESS, retval
          assert self.map.width == 480
          assert self.map.height == 480
  
  
  class MapSetWKTTestCase(MapTestCase):
  
      def testOGCWKT(self):
          self.map.setWKTProjection('PROJCS["unnamed", PROJECTION["Albers_Conic_Equal_Area"], '
                                    'PARAMETER["standard_parallel_1", 65], PARAMETER["standard_parallel_2", 55], '
                                    'PARAMETER["latitude_of_center", 0], PARAMETER["longitude_of_center", -153], '
                                    'PARAMETER["false_easting", -4943910.68], PARAMETER["false_northing", 0]]')
          proj4 = self.map.getProjection()
  
          assert proj4.find('+proj=aea') != -1
          assert proj4.find('+ellps=WGS84') != -1
          assert (mapscript.projectionObj(proj4)).getUnits() != mapscript.MS_DD
  
      def testESRIWKT(self):
          self.map.setWKTProjection('ESRI::PROJCS["Pulkovo_1995_GK_Zone_2", GEOGCS["GCS_Pulkovo_1995", '
                                    'DATUM["D_Pulkovo_1995", SPHEROID["Krasovsky_1940", 6378245, 298.3]], '
                                    'PRIMEM["Greenwich", 0], '
                                    'UNIT["Degree", 0.017453292519943295]], PROJECTION["Gauss_Kruger"], '
                                    'PARAMETER["False_Easting", 2500000], '
                                    'PARAMETER["False_Northing", 0], PARAMETER["Central_Meridian", 9], '
                                    'PARAMETER["Scale_Factor", 1], '
                                    'PARAMETER["Latitude_Of_Origin", 0], UNIT["Meter", 1]]')
          proj4 = self.map.getProjection()
  
          assert proj4.find('+proj=tmerc') != -1
          assert proj4.find('+ellps=krass') != -1
          assert (mapscript.projectionObj(proj4)).getUnits() != mapscript.MS_DD
  
      def testWellKnownGEOGCS(self):
          self.map.setWKTProjection('WGS84')
          proj4 = self.map.getProjection()
          assert proj4.find('+proj=longlat') != -1, proj4
          assert proj4.find('+datum=WGS84') != -1, proj4
          assert (mapscript.projectionObj(proj4)).getUnits() != mapscript.MS_METERS
  
  
  if __name__ == '__main__':
      unittest.main()
  