Orb/python/orb/lib.py
changeset 2 932c358ece3e
child 4 468f4c8d3d5b
equal deleted inserted replaced
1:82f11024044a 2:932c358ece3e
       
     1 # Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved.
       
     2 # This component and the accompanying materials are made available under the terms of the License 
       
     3 # "Eclipse Public License v1.0" which accompanies this distribution, 
       
     4 # and is available at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     5 #
       
     6 # Initial Contributors:
       
     7 # Nokia Corporation - initial contribution.
       
     8 #
       
     9 # Contributors:
       
    10 #
       
    11 # Description:
       
    12 #
       
    13 import os
       
    14 import unittest
       
    15 import xml
       
    16 import re
       
    17 import sys
       
    18 from optparse import OptionParser
       
    19 from cStringIO import StringIO
       
    20 from xml.etree import ElementTree as etree
       
    21 
       
    22 nmtoken_regex = re.compile("[^a-zA-Z0-9_\.]")
       
    23 
       
    24 def scan(dir):
       
    25     for root, _, files in os.walk(dir):
       
    26         for fname in files:
       
    27             yield os.path.join(root, fname) 
       
    28             
       
    29 def xml_decl():
       
    30     return """<?xml version="1.0" encoding="UTF-8"?>"""
       
    31     
       
    32 def doctype_identifier(doctype):
       
    33     """
       
    34     Return a doctype declaration string for a given doctype.
       
    35     Understands DITA and cxxapiref DITA specialisation doctypes.
       
    36     """
       
    37     # DITA Doctype Identifiers (no specific version number in identifier means latest DITA DTD version)
       
    38     if doctype == "map":
       
    39         return """<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">"""
       
    40     elif doctype == "topic":
       
    41         return """<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">"""
       
    42     elif doctype == "task":
       
    43         return """<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">"""
       
    44     elif doctype == "reference":
       
    45         return """<!DOCTYPE reference PUBLIC "-//OASIS//DTD DITA Reference//EN" "reference.dtd">"""
       
    46     elif doctype == "glossary":
       
    47         return """<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DITA Glossary//EN" "glossary.dtd">"""
       
    48     elif doctype == "concept":
       
    49         return """<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">"""
       
    50     elif doctype == "bookmap":
       
    51         return """<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd">""" 
       
    52     # cxxapiref DITA specialisation Doctype Identifiers
       
    53     elif doctype == "cxxUnion":
       
    54         return """<!DOCTYPE cxxUnion PUBLIC "-//NOKIA//DTD DITA C++ API Union Reference Type v0.5.0//EN" "dtd/cxxUnion.dtd">"""   
       
    55     elif doctype == "cxxStruct":
       
    56         return """<!DOCTYPE cxxStruct PUBLIC "-//NOKIA//DTD DITA C++ API Struct Reference Type v0.5.0//EN" "dtd/cxxStruct.dtd">"""
       
    57     elif doctype == "cxxPackage":
       
    58         return """<!DOCTYPE cxxPackage PUBLIC "-//NOKIA//DTD DITA cxx API Package Reference Type v0.5.0//EN" "dtd/cxxPackage.dtd">"""
       
    59     elif doctype == "cxxFile":
       
    60         return """<!DOCTYPE cxxFile PUBLIC "-//NOKIA//DTD DITA C++ API File Reference Type v0.5.0//EN" "dtd/cxxFile.dtd">"""
       
    61     elif doctype == "cxxClass":
       
    62         return """<!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.5.0//EN" "dtd/cxxClass.dtd">"""
       
    63     elif doctype == "cxxAPIMap":
       
    64         return """<!DOCTYPE cxxAPIMap PUBLIC "-//NOKIA//DTD DITA C++ API Map Reference Type v0.5.0//EN" "dtd/cxxAPIMap.dtd" >"""
       
    65     else:
       
    66         raise Exception('Unknown Doctype \"%s\"' % doctype)
       
    67 
       
    68 def get_valid_nmtoken(attribute_value):
       
    69     new_value = attribute_value
       
    70     matches = nmtoken_regex.findall(new_value)
       
    71     for char in set(matches):
       
    72         new_value = new_value.replace(char,"")
       
    73     return new_value
       
    74 
       
    75 class XmlParser(object):
       
    76     """
       
    77     Simple class that reads an XML and returns its id
       
    78 
       
    79     >>> xp = XmlParser()
       
    80     >>> xp.parse(StringIO("<root id='rootid'>some content</root>"))
       
    81     'rootid'
       
    82     """
       
    83     def parse(self, xmlfile):
       
    84         try:
       
    85             root = etree.parse(xmlfile).getroot()
       
    86         except xml.parsers.expat.ExpatError, e:
       
    87             sys.stderr.write("ERROR: %s could not be parse: %s\n" % (xmlfile, str(e)))
       
    88             return ""
       
    89         if 'id' not in root.attrib:
       
    90             return ""
       
    91         return root.attrib['id']
       
    92 
       
    93 def main(func, version):
       
    94     usage = "usage: %prog <Path to the XML content>"
       
    95     parser = OptionParser(usage, version='%prog ' + version)
       
    96     (options, args) = parser.parse_args()
       
    97     if len(args) < 1:
       
    98         parser.print_help()
       
    99         parser.error("Please supply the path to the XML content")
       
   100     func(args[0])
       
   101     
       
   102 ######################################
       
   103 # Test code
       
   104 ######################################
       
   105 
       
   106 class Testxml_decl(unittest.TestCase):
       
   107     def testi_can_return_anxml_declaration(self):
       
   108         self.assertEquals(xml_decl(), """<?xml version="1.0" encoding="UTF-8"?>""")
       
   109     
       
   110     
       
   111 class Testdoctype_identifier(unittest.TestCase):
       
   112     
       
   113     def test_i_raise_an_exception_for_an_unknown_doctype(self):
       
   114         self.assertRaises(Exception, doctype_identifier, "invaliddoctype")
       
   115         
       
   116     def test_i_can_return_a_map_doctype_identifier(self):        
       
   117         self.assertEquals(doctype_identifier("map"), """<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA Map//EN" "map.dtd">""")
       
   118         
       
   119     def test_i_can_return_a_topic_doctype_identifier(self):        
       
   120         self.assertEquals(doctype_identifier("topic"), """<!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">""")
       
   121         
       
   122     def test_i_can_return_a_task_doctype_identifier(self):        
       
   123         self.assertEquals(doctype_identifier("task"), """<!DOCTYPE task PUBLIC "-//OASIS//DTD DITA Task//EN" "task.dtd">""")
       
   124         
       
   125     def test_i_can_return_a_reference_doctype_identifier(self):        
       
   126         self.assertEquals(doctype_identifier("reference"), """<!DOCTYPE reference PUBLIC "-//OASIS//DTD DITA Reference//EN" "reference.dtd">""")
       
   127         
       
   128     def test_i_can_return_a_glossary_doctype_identifier(self):        
       
   129         self.assertEquals(doctype_identifier("glossary"), """<!DOCTYPE glossary PUBLIC "-//OASIS//DTD DITA Glossary//EN" "glossary.dtd">""")
       
   130         
       
   131     def test_i_can_return_a_concept_doctype_identifier(self):        
       
   132         self.assertEquals(doctype_identifier("concept"), """<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">""")
       
   133         
       
   134     def test_i_can_return_a_bookmap_doctype_identifier(self):        
       
   135         self.assertEquals(doctype_identifier("bookmap"), """<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd">""")
       
   136 
       
   137     def test_i_can_return_a_cxxUnion_doctype_identifier(self):        
       
   138         self.assertEquals(doctype_identifier("cxxUnion"), """<!DOCTYPE cxxUnion PUBLIC "-//NOKIA//DTD DITA C++ API Union Reference Type v0.5.0//EN" "dtd/cxxUnion.dtd">""")
       
   139     
       
   140     def test_i_can_return_a_cxxStruct_doctype_identifier(self):        
       
   141         self.assertEquals(doctype_identifier("cxxStruct"), """<!DOCTYPE cxxStruct PUBLIC "-//NOKIA//DTD DITA C++ API Struct Reference Type v0.5.0//EN" "dtd/cxxStruct.dtd">""")
       
   142         
       
   143     def test_i_can_return_a_cxxPackage_doctype_identifier(self):        
       
   144         self.assertEquals(doctype_identifier("cxxPackage"), """<!DOCTYPE cxxPackage PUBLIC "-//NOKIA//DTD DITA cxx API Package Reference Type v0.5.0//EN" "dtd/cxxPackage.dtd">""")
       
   145         
       
   146     def test_i_can_return_a_cxxFile_doctype_identifier(self):        
       
   147         self.assertEquals(doctype_identifier("cxxFile"), """<!DOCTYPE cxxFile PUBLIC "-//NOKIA//DTD DITA C++ API File Reference Type v0.5.0//EN" "dtd/cxxFile.dtd">""")
       
   148         
       
   149     def test_i_can_return_a_cxxClass_doctype_identifier(self):        
       
   150         self.assertEquals(doctype_identifier("cxxClass"), """<!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.5.0//EN" "dtd/cxxClass.dtd">""")
       
   151         
       
   152     def test_i_can_return_a_cxxAPIMap_doctype_identifier(self):        
       
   153         self.assertEquals(doctype_identifier("cxxAPIMap"), """<!DOCTYPE cxxAPIMap PUBLIC "-//NOKIA//DTD DITA C++ API Map Reference Type v0.5.0//EN" "dtd/cxxAPIMap.dtd" >""")
       
   154         
       
   155                 
       
   156 class Testget_valid_nmtoken(unittest.TestCase):
       
   157     
       
   158     def test_i_remove_non_alpha_numeric_characters(self):
       
   159         input = "this is an alphanumeric string with non alpha numeric characters inside.()_+=-string0123456789"
       
   160         expout = "thisisanalphanumericstringwithnonalphanumericcharactersinside._string0123456789"
       
   161         output = get_valid_nmtoken(input)
       
   162         self.assertEquals(output, expout)        
       
   163         
       
   164         
       
   165 class StubXmlParser(object):
       
   166     def parse(self, path):
       
   167         return "GUID-BED8A733-2ED7-31AD-A911-C1F4707C67F"
       
   168 
       
   169 
       
   170 class TestXmlParser(unittest.TestCase):
       
   171     def test_i_issue_a_warning_and_continue_if_a_file_is_invalid(self):
       
   172         xml = XmlParser()
       
   173         try:
       
   174             xml.parse(StringIO("<foo><bar</foo>"))
       
   175         except Exception, e:
       
   176             self.fail("I shouldn't have raised an exception. Exception was %s" % e) 
       
   177 
       
   178     def test_i_issue_a_warning_and_continue_if_a_file_does_not_have_an_id(self):
       
   179         xml = XmlParser()
       
   180         try:
       
   181             id = xml.parse(StringIO(brokencxxclass))
       
   182         except Exception:
       
   183             self.fail("I shouldn't have raised an exception")
       
   184         self.assertTrue(id == "") 
       
   185 
       
   186     def test_i_return_a_files_id(self):
       
   187         xml = XmlParser()
       
   188         id = xml.parse(StringIO(cxxclass))
       
   189         self.assertTrue(id == "class_c_active_scheduler")
       
   190         
       
   191 brokencxxclass = """<?xml version='1.0' encoding='UTF-8' standalone='no'?>
       
   192 <!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.5.0//EN" "dtd/cxxClass.dtd" >
       
   193 <cxxClass>
       
   194     <apiName>CActiveScheduler</apiName>
       
   195     <shortdesc/>
       
   196 </cxxClass>
       
   197 """
       
   198 
       
   199 cxxclass = """<?xml version='1.0' encoding='UTF-8' standalone='no'?>
       
   200 <!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.5.0//EN" "dtd/cxxClass.dtd" >
       
   201 <cxxClass id="class_c_active_scheduler">
       
   202     <apiName>CActiveScheduler</apiName>
       
   203     <shortdesc/>
       
   204 </cxxClass>
       
   205 """