Commit 7bf44fe5 authored by Christian Ledermann's avatar Christian Ledermann

move from lists to generators to fetch the contents of a container or kml, use...

move from lists to generators to fetch the contents of a container or kml, use getter and setter for feature.styleUrl
parent f67a7e85
......@@ -19,13 +19,9 @@ This library only implements a subset of Atom that is useful with KML
import logging
logger = logging.getLogger('fastkml.atom')
from config import etree
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
NS = '{http://www.w3.org/2005/Atom}'
import re
regex = r"^[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+\.)*[a-zA-Z]{2,4}$"
......@@ -75,7 +71,7 @@ class Link(object):
def __init__(self, ns=None, href=None, rel=None, type=None,
hreflang=None, title=None, lenght=None):
if ns == None:
self.ns = '{http://www.w3.org/2005/Atom}'
self.ns = NS
else:
self.ns = ns
self.href = href
......@@ -129,6 +125,7 @@ class _Person(object):
entity. It has one required element, name, and two optional elements:
uri, email.
"""
__name__ = None
ns = None
name = None
......@@ -142,7 +139,7 @@ class _Person(object):
def __init__(self, ns=None, name=None, uri=None, email=None):
if ns == None:
self.ns = '{http://www.w3.org/2005/Atom}'
self.ns = NS
else:
self.ns = ns
self.name = name
......
......@@ -35,7 +35,7 @@ class _BaseObject(object):
if self.targetId:
element.set('targetId', self.targetId)
else:
raise NotImplementedError
raise NotImplementedError("Call of abstract base class, subclasses implement this!")
return element
......@@ -44,9 +44,17 @@ class _BaseObject(object):
def from_element(self, element):
if self.ns + self.__name__ != element.tag:
raise TypeError
raise TypeError("Call of abstract base class, subclasses implement this!")
else:
if element.get('id'):
self.id = element.get('id')
if element.get('targetId'):
self.targetId = element.get('targetId')
def to_string(self, prettyprint=True):
""" Return the KML Object as serialized xml """
if config.LXML and prettyprint:
return etree.tostring(self.etree_element(), encoding='utf-8',
pretty_print=True)
else:
return etree.tostring(self.etree_element(), encoding='utf-8')
# -*- coding: utf-8 -*-
"""frequently used constants and abstract base classes"""
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
NS = '{http://www.opengis.net/kml/2.2}'
......@@ -15,19 +15,19 @@ from geometry import MultiPoint, MultiLineString, MultiPolygon
from geometry import LinearRing
from datetime import datetime, date
# note that there are some ISO 8601 timeparsers at pypi
# but in my tests all of them had some errors so we rely on the
# tried and tested dateutil here which is more stable. As a side effect
# we can also parse non ISO compliant dateTimes
import dateutil.parser
import logging
logger = logging.getLogger('fastkml.kml')
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
import config
from config import etree
from base import _BaseObject
from styles import StyleUrl, Style, StyleMap, _StyleSelector
......@@ -80,24 +80,29 @@ class KML(object):
def to_string(self, prettyprint=False):
""" Returm the KML Object as xml """
if LXML and prettyprint:
""" Return the KML Object as serialized xml """
if config.LXML and prettyprint:
return etree.tostring(self.etree_element(), encoding='utf-8',
pretty_print=True)
else:
return etree.tostring(self.etree_element(), encoding='utf-8')
def features(self):
""" return a list of features """
#XXX yield feature, test if they are valid features
return self._features
""" iterate over features """
for feature in self._features:
if isinstance(feature, (Document, Folder, Placemark)):
yield feature
else:
raise TypeError(
"Features must be instances of (Document, Folder, Placemark)")
def append(self, kmlobj):
""" append a feature """
if isinstance(kmlobj, (Document, Folder, Placemark)):
self._features.append(kmlobj)
else:
raise TypeError
raise TypeError(
"Features must be instances of (Document, Folder, Placemark)")
class _Feature(_BaseObject):
"""
......@@ -110,6 +115,7 @@ class _Feature(_BaseObject):
#PhotoOverlay,
#ScreenOverlay
"""
name = None
#User-defined text displayed in the 3D viewer as the label for the
#object (for example, for a Placemark, Folder, or NetworkLink).
description = None
......@@ -123,7 +129,7 @@ class _Feature(_BaseObject):
#Boolean value. Specifies whether a Document or Folder appears
#closed or open when first loaded into the Places panel.
#0=collapsed (the default), 1=expanded.
styleUrl = None
_styleUrl = None
#URL of a <Style> or <StyleMap> defined in a Document.
#If the style is in the same file, use a # reference.
#If the style is defined in an external file, use a full URL
......@@ -137,18 +143,37 @@ class _Feature(_BaseObject):
def __init__(self, ns=None, id=None, name=None, description=None,
styles=None, styleUrl=None):
self.id = id
super(_Feature, self).__init__(ns, id)
self.name=name
self.description=description
self.styleUrl = styleUrl
if styleUrl is not None:
self.styleUrl = styleUrl
self._styles = []
if styles:
for style in styles:
self.append_style(style)
if ns == None:
self.ns = config.NS
@property
def styleUrl(self):
""" Returns the url only, not a full StyleUrl object.
if you need the full StyleUrl use _styleUrl """
if isinstance(self._styleUrl, StyleUrl):
return self._styleUrl.url
@styleUrl.setter
def styleUrl(self, styleurl):
""" you may pass a StyleUrl Object, a string or None """
if isinstance(styleurl, StyleUrl):
self._styleUrl = styleurl
elif isinstance(styleurl, basestring):
s = StyleUrl(self.ns, url=styleurl)
self._styleUrl = s
elif styleurl is None:
self._styleUrl = None
else:
self.ns = ns
raise ValueError
def append_style(self, style):
""" append a style to the feature """
......@@ -167,33 +192,28 @@ class _Feature(_BaseObject):
def etree_element(self):
if self.__name__:
element = etree.Element(self.ns + self.__name__)
if self.id:
element.set('id', self.id)
if self.name:
name = etree.SubElement(element, "%sname" %self.ns)
name.text = self.name
if self.description:
description =etree.SubElement(element, "%sdescription" %self.ns)
description.text = self.description
visibility = etree.SubElement(element, "%svisibility" %self.ns)
visibility.text = str(self.visibility)
isopen = etree.SubElement(element, "%sopen" %self.ns)
isopen.text = str(self.isopen)
if self.styleUrl:
styleUrl = StyleUrl( self.ns, self.styleUrl)
element.append(styleUrl.etree_element())
for style in self.styles():
element.append(style.etree_element())
if (self._time_span is not None) and (self._time_stamp is not None):
raise ValueError
#elif self._time_span:
# timespan = TimeStamp(self.ns, begin=self._time_span[0][0],
# begin_res=self._time_span[0][1])
element = super(_Feature, self).etree_element()
if self.name:
name = etree.SubElement(element, "%sname" %self.ns)
name.text = self.name
if self.description:
description =etree.SubElement(element, "%sdescription" %self.ns)
description.text = self.description
visibility = etree.SubElement(element, "%svisibility" %self.ns)
visibility.text = str(self.visibility)
isopen = etree.SubElement(element, "%sopen" %self.ns)
isopen.text = str(self.isopen)
if self._styleUrl is not None:
element.append(self._styleUrl.etree_element())
for style in self.styles():
element.append(style.etree_element())
if (self._time_span is not None) and (self._time_stamp is not None):
raise ValueError
#elif self._time_span:
# timespan = TimeStamp(self.ns, begin=self._time_span[0][0],
# begin_res=self._time_span[0][1])
else:
raise NotImplementedError
return element
......@@ -226,10 +246,11 @@ class _Feature(_BaseObject):
s.from_element(style)
self.append_style(s)
style_url = element.find('%sstyleUrl' % self.ns)
if style_url:
if style_url is not None:
s = StyleUrl(self.ns)
s.from_element(style_url)
self.styleUrl = s.url
self._styleUrl = s
#XXX Timespan/stamp
......@@ -248,14 +269,15 @@ class _Container(_Feature):
def __init__(self, ns=None, id=None, name=None, description=None):
super(_Container, self).__init__(ns, id, name, description)
self._features =[]
if ns == None:
self.ns = config.NS
else:
self.ns = ns
def features(self):
""" return a list of features """
return self._features
""" iterate over features """
for feature in self._features:
if isinstance(feature, (Folder, Placemark)):
yield feature
else:
raise TypeError(
"Features must be instances of (Folder, Placemark)")
def etree_element(self):
element = super(_Container, self).etree_element()
......
......@@ -9,14 +9,10 @@ import logging
logger = logging.getLogger('fastkml.styles')
import config
from config import etree
from base import _BaseObject
try:
from lxml import etree
LXML = True
except ImportError:
import xml.etree.ElementTree as etree
LXML = False
class StyleUrl(_BaseObject):
......@@ -25,32 +21,25 @@ class StyleUrl(_BaseObject):
is in the same file, use a # reference. If the style is defined in
an external file, use a full URL along with # referencing.
"""
__name__ = 'styleUrl'
url = None
def __init__(self, ns=None, url=None):
def __init__(self, ns=None, id=None, url=None):
super(StyleUrl, self).__init__(ns, id)
self.url = url
if ns == None:
self.ns = config.NS
else:
self.ns = ns
def etree_element(self):
if self.url:
element = etree.Element(self.ns + "styleUrl")
element = super(StyleUrl, self).etree_element()
element.text = self.url
return element
else:
logger.critical('No url given for styleUrl')
raise ValueError
def from_element(self, element):
if self.ns + "styleUrl" != element.tag:
raise TypeError
else:
self.url = element.text
super(StyleUrl, self).from_element(element)
self.url = element.text
class _StyleSelector(_BaseObject):
......@@ -62,19 +51,6 @@ class _StyleSelector(_BaseObject):
by its id and its url.
"""
def etree_element(self):
element = etree.Element(self.ns + self.__name__)
if self.id:
element.set('id', self.id)
return element
def from_element(self, element):
if self.ns + self.__name__ != element.tag:
raise TypeError
else:
if element.get('id'):
self.id = element.get('id')
class Style(_StyleSelector):
"""
......@@ -179,7 +155,6 @@ class StyleMap(_StyleSelector):
normal = StyleUrl(self.ns)
normal.from_element(style_url)
else:
import ipdb; ipdb.set_trace()
raise ValueError
self.normal = normal
else:
......@@ -226,19 +201,13 @@ class _ColorStyle(_BaseObject):
# A value of random applies a random linear scale to the base <color>
def __init__(self, ns=None, id=None, color=None, colorMode=None):
self.id = id
if ns == None:
self.ns = config.NS
else:
self.ns = ns
super(_ColorStyle, self).__init__(ns, id)
self.color = color
self.colorMode = colorMode
def etree_element(self):
element = etree.Element(self.ns + self.__name__)
if self.id:
element.set('id', self.id)
element = super(_ColorStyle, self).etree_element()
if self.color:
color = etree.SubElement(element, "%scolor" %self.ns)
color.text = self.color
......
......@@ -3,6 +3,8 @@ import unittest
from fastkml import kml
from fastkml import styles
from fastkml import base
from fastkml import config
import xml.etree.ElementTree as etree
from shapely.geometry import Point, LineString, Polygon
from shapely.geometry import MultiPoint, MultiLineString, MultiPolygon
......@@ -13,9 +15,35 @@ class BaseClassesTestCase(unittest.TestCase):
and a TypeError on from_element """
def test_BaseObject(self):
pass
bo = base._BaseObject(id='id0')
self.assertEqual(bo.id, 'id0')
self.assertEqual(bo.ns, config.NS)
self.assertEqual(bo.targetId, None)
self.assertEqual(bo.__name__, None)
bo.targetId = 'target'
self.assertEqual(bo.targetId, 'target')
bo.ns =''
bo.id =None
self.assertEqual(bo.id, None)
self.assertEqual(bo.ns, '')
self.assertRaises(NotImplementedError, bo.etree_element)
element = etree.Element(config.NS + 'Base')
self.assertRaises(TypeError, bo.from_element)
self.assertRaises(TypeError, bo.from_element, element)
bo.__name__ = 'NotABaseObject'
self.assertRaises(TypeError, bo.from_element, element)
#Note that we can coax baseclasses not to throw errors
bo.__name__ = 'Base'
bo.ns = config.NS
bo.from_element(element)
self.assertEqual(bo.id, None)
self.assertEqual(bo.ns, config.NS)
self.assertFalse(bo.etree_element(), None)
self.assertTrue(len(bo.to_string()) > 1)
def test_Feature(self):
f = kml._Feature(name='A Feature')
f.styleUrl = '#default'
pass
def test_Container(self):
......@@ -38,7 +66,7 @@ class BuildKmlTestCase(unittest.TestCase):
def test_kml(self):
""" kml file without contents """
k = kml.KML()
self.assertEqual(len(k.features()),0)
self.assertEqual(len( list(k.features())),0)
self.assertEqual( k.to_string(),
'<ns0:kml xmlns:ns0="http://www.opengis.net/kml/2.2"/>')
k2 = kml.KML()
......@@ -56,8 +84,8 @@ class BuildKmlTestCase(unittest.TestCase):
k.append(f)
f2 = kml.Folder(ns, 'id2', 'name2', 'description2')
k.append(f2)
self.assertEqual(len(k.features()),2)
self.assertEqual(len( k.features()[0].features()),1)
self.assertEqual(len(list(k.features())),2)
self.assertEqual(len( list( list(k.features())[0].features())),1)
k2 = kml.KML()
s = k.to_string()
k2.from_string(s)
......@@ -73,7 +101,7 @@ class BuildKmlTestCase(unittest.TestCase):
p2.geometry = LineString([(0, 0, 0), (1, 1, 1)])
k.append(p)
k.append(p2)
self.assertEqual(len(k.features()),2)
self.assertEqual(len(list(k.features())),2)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -96,8 +124,8 @@ class BuildKmlTestCase(unittest.TestCase):
#p2 does not have a geometry!
f2.append(p)
nf.append(p2)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),2)
self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(list((list(k.features())[0].features()))),2)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -136,8 +164,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),2)
self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(list(list(k.features())[0].features())),2)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -187,8 +215,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(k.features()[0].features()),3)
self.assertEqual(len(list(k.features())),1)
self.assertEqual(len(list(list(k.features())[0].features())),3)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -208,8 +236,8 @@ class KmlFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(k.features()[0].name, "Simple placemark")
self.assertEqual(len(list(k.features())),1)
self.assertEqual(list(k.features())[0].name, "Simple placemark")
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -225,9 +253,9 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
k.features()[0].geometry, Polygon))
list(k.features())[0].geometry, Polygon))
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -280,10 +308,10 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark></kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
k.features()[0].geometry, MultiPoint))
self.assertEqual(len(k.features()[0].geometry.geoms), 12)
list(k.features())[0].geometry, MultiPoint))
self.assertEqual(len(list(k.features())[0].geometry.geoms), 12)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -304,10 +332,10 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
k.features()[0].geometry, MultiLineString))
self.assertEqual(len(k.features()[0].geometry.geoms), 4)
list(k.features())[0].geometry, MultiLineString))
self.assertEqual(len(list(k.features())[0].geometry.geoms), 4)
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -322,15 +350,52 @@ class KmlFromStringTestCase( unittest.TestCase ):
</Placemark> </kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
k.features()[0].geometry, MultiPolygon))
list(k.features())[0].geometry, MultiPolygon))
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
class StyleTestCase( unittest.TestCase ):
def test_styleurl(self):
f = kml.Document()
f.styleUrl = '#somestyle'
self.assertEqual(f.styleUrl, '#somestyle')
self.assertTrue(isinstance(f._styleUrl, styles.StyleUrl))
s = styles.StyleUrl(config.NS, url='#otherstyle')
f.styleUrl = s
self.assertTrue(isinstance(f._styleUrl, styles.StyleUrl))
self.assertEqual(f.styleUrl, '#otherstyle')
class StyleFromStringTestCase( unittest.TestCase ):
def test_styleurl(self):
doc = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Document.kml</name>
<open>1</open>
<styleUrl>#default</styleUrl>
</Document>
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(list(k.features())),1)
self.assertEqual(list(k.features())[0].styleUrl, '#default')
k2 = kml.KML()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
def test_balloonstyle(self):
pass
def test_labelstyle(self):
doc = """<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
......@@ -346,10 +411,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0]
list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.LabelStyle))
self.assertEqual(style.color, 'ff0000cc')
self.assertEqual(style.colorMode, None)
......@@ -376,10 +441,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list((k.features()))),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0]
list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.IconStyle))
self.assertEqual(style.color, 'ff00ff00')
self.assertEqual(style.scale, 1.1)
......@@ -406,10 +471,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0]
list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.LineStyle))
self.assertEqual(style.color, '7f0000ff')
self.assertEqual(style.width, 4)
......@@ -432,13 +497,13 @@ class StyleFromStringTestCase( unittest.TestCase ):
</Style>
</Document>
</kml>"""
#XXX fil and outline
#XXX fill and outline
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())[0]
list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(list(k.features())[0].styles())[0].styles())[0]
self.assertTrue(isinstance(style, styles.PolyStyle))
self.assertEqual(style.color, 'ff0000cc')
self.assertEqual(style.colorMode, 'random')
......@@ -478,10 +543,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.Style))
style = list(list(k.features()[0].styles())[0].styles())
list(list(k.features())[0].styles())[0], styles.Style))
style = list(list(list(k.features())[0].styles())[0].styles())
self.assertEqual(len(style), 4)
k2 = kml.KML()
k2.from_string(k.to_string())
......@@ -506,15 +571,16 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.StyleMap))
sm = list(list(k.features()[0].styles()))[0]
list(list(k.features())[0].styles())[0], styles.StyleMap))
sm = list(list(list(k.features())[0].styles()))[0]
self.assertTrue(isinstance(sm.normal, styles.StyleUrl))
self.assertEqual(sm.normal.url, '#normalState')
self.assertTrue(isinstance(sm.highlight, styles.StyleUrl))
self.assertEqual(sm.highlight.url, '#highlightState')
k2 = kml.KML()
ks = k.to_string()
k2.from_string(k.to_string())
self.assertEqual(k.to_string(), k2.to_string())
......@@ -549,10 +615,10 @@ class StyleFromStringTestCase( unittest.TestCase ):
</kml>"""
k = kml.KML()
k.from_string(doc)
self.assertEqual(len(k.features()),1)
self.assertEqual(len(list(k.features())),1)
self.assertTrue(isinstance(
list(k.features()[0].styles())[0], styles.StyleMap))
sm = list(list(k.features()[0].styles()))[0]
list(list(k.features())[0].styles())[0], styles.StyleMap))
sm = list(list(list(k.features())[0].styles()))[0]
self.assertTrue(isinstance(sm.normal, styles.Style))
self.assertEqual(len(list(sm.normal.styles())), 1)
self.assertTrue(isinstance(list(sm.normal.styles())[0], styles.LabelStyle))
......@@ -570,6 +636,7 @@ def test_suite():
suite.addTest(unittest.makeSuite( KmlFromStringTestCase ))
suite.addTest(unittest.makeSuite( BuildKmlTestCase ))
suite.addTest(unittest.makeSuite( StyleFromStringTestCase ))
suite.addTest(unittest.makeSuite(BaseClassesTestCase))
return suite
if __name__ == '__main__':
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment