## @file
# This file contain unit test for DecParser
#
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

import os
import unittest
from Logger.Log import FatalError

from Parser.DecParser import \
    Dec, \
    _DecDefine, \
    _DecLibraryclass, \
    _DecPcd, \
    _DecGuid, \
    FileContent, \
    _DecBase, \
    CleanString
    
from Object.Parser.DecObject import _DecComments

#
# Test CleanString
#
class CleanStringTestCase(unittest.TestCase):
    def testCleanString(self):
        Line, Comment = CleanString('')
        self.assertEqual(Line, '')
        self.assertEqual(Comment, '')
        
        Line, Comment = CleanString('line without comment')
        self.assertEqual(Line, 'line without comment')
        self.assertEqual(Comment, '')
        
        Line, Comment = CleanString('# pure comment')
        self.assertEqual(Line, '')
        self.assertEqual(Comment, '# pure comment')
        
        Line, Comment = CleanString('line # and comment')
        self.assertEqual(Line, 'line')
        self.assertEqual(Comment, '# and comment')
    
    def testCleanStringCpp(self):
        Line, Comment = CleanString('line // and comment', AllowCppStyleComment = True)
        self.assertEqual(Line, 'line')
        self.assertEqual(Comment, '# and comment')

#
# Test _DecBase._MacroParser function
#
class MacroParserTestCase(unittest.TestCase):
    def setUp(self):
        self.dec = _DecBase(FileContent('dummy', []))
    
    def testCorrectMacro(self):
        self.dec._MacroParser('DEFINE MARCRO1 = test1')
        self.failIf('MARCRO1' not in self.dec._LocalMacro)
        self.assertEqual(self.dec._LocalMacro['MARCRO1'], 'test1')
    
    def testErrorMacro1(self):
        # Raise fatal error, macro name must be upper case letter
        self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE not_upper_case = test2')
    
    def testErrorMacro2(self):
        # No macro name given
        self.assertRaises(FatalError, self.dec._MacroParser, 'DEFINE ')

#
# Test _DecBase._TryBackSlash function
#
class TryBackSlashTestCase(unittest.TestCase):
    def setUp(self):
        Content = [
            # Right case
            'test no backslash',
            
            'test with backslash \\',
            'continue second line',
            
            # Do not precede with whitespace
            '\\',
            
            # Empty line after backlash is not allowed
            'line with backslash \\',
            ''
        ]
        self.dec = _DecBase(FileContent('dummy', Content))
    
    def testBackSlash(self):
        #
        # Right case, assert return values
        #
        ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), [])
        self.assertEqual(ConcatLine, 'test no backslash')
        self.assertEqual(CommentList, [])
        
        ConcatLine, CommentList = self.dec._TryBackSlash(self.dec._RawData.GetNextLine(), [])
        self.assertEqual(CommentList, [])
        self.assertEqual(ConcatLine, 'test with backslash continue second line')
        
        #
        # Error cases, assert raise exception
        #
        self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), [])
        self.assertRaises(FatalError, self.dec._TryBackSlash, self.dec._RawData.GetNextLine(), [])

#
# Test _DecBase.Parse function
#
class DataItem(_DecComments):
    def __init__(self):
        _DecComments.__init__(self)
        self.String = ''

class Data(_DecComments):
    def __init__(self):
        _DecComments.__init__(self)
        # List of DataItem
        self.ItemList = []

class TestInner(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        self.ItemObject = Data()
    
    def _StopCurrentParsing(self, Line):
        return Line == '[TOP]'
    
    def _ParseItem(self):
        Item = DataItem()
        Item.String = self._RawData.CurrentLine
        self.ItemObject.ItemList.append(Item)
        return Item
    
    def _TailCommentStrategy(self, Comment):
        return Comment.find('@comment') != -1

class TestTop(_DecBase):
    def __init__(self, RawData):
        _DecBase.__init__(self, RawData)
        # List of Data
        self.ItemObject = []
    
    # Top parser
    def _StopCurrentParsing(self, Line):
        return False

    def _ParseItem(self):
        TestParser = TestInner(self._RawData)
        TestParser.Parse()
        self.ItemObject.append(TestParser.ItemObject)
        return TestParser.ItemObject

class ParseTestCase(unittest.TestCase):        
    def setUp(self):
        pass
    
    def testParse(self):
        Content = \
        '''# Top comment
        [TOP]
          # sub1 head comment
          (test item has both head and tail comment) # sub1 tail comment
          # sub2 head comment
          (test item has head and special tail comment)
          # @comment test TailCommentStrategy branch
          
          (test item has no comment)
        
        # test NextLine branch
        [TOP]
          sub-item
        '''
        dec = TestTop(FileContent('dummy', Content.splitlines()))
        dec.Parse()
        
        # Two sections
        self.assertEqual(len(dec.ItemObject), 2)
        
        data = dec.ItemObject[0]
        self.assertEqual(data._HeadComment[0][0], '# Top comment')
        self.assertEqual(data._HeadComment[0][1], 1)
        
        # 3 subitems
        self.assertEqual(len(data.ItemList), 3)
        
        dataitem = data.ItemList[0]
        self.assertEqual(dataitem.String, '(test item has both head and tail comment)')
        # Comment content
        self.assertEqual(dataitem._HeadComment[0][0], '# sub1 head comment')
        self.assertEqual(dataitem._TailComment[0][0], '# sub1 tail comment')
        # Comment line number
        self.assertEqual(dataitem._HeadComment[0][1], 3)
        self.assertEqual(dataitem._TailComment[0][1], 4)
        
        dataitem = data.ItemList[1]
        self.assertEqual(dataitem.String, '(test item has head and special tail comment)')
        # Comment content
        self.assertEqual(dataitem._HeadComment[0][0], '# sub2 head comment')
        self.assertEqual(dataitem._TailComment[0][0], '# @comment test TailCommentStrategy branch')
        # Comment line number
        self.assertEqual(dataitem._HeadComment[0][1], 5)
        self.assertEqual(dataitem._TailComment[0][1], 7)
        
        dataitem = data.ItemList[2]
        self.assertEqual(dataitem.String, '(test item has no comment)')
        # Comment content
        self.assertEqual(dataitem._HeadComment, [])
        self.assertEqual(dataitem._TailComment, [])
        
        data = dec.ItemObject[1]
        self.assertEqual(data._HeadComment[0][0], '# test NextLine branch')
        self.assertEqual(data._HeadComment[0][1], 11)
        
        # 1 subitems
        self.assertEqual(len(data.ItemList), 1)
        
        dataitem = data.ItemList[0]
        self.assertEqual(dataitem.String, 'sub-item')
        self.assertEqual(dataitem._HeadComment, [])
        self.assertEqual(dataitem._TailComment, [])

#
# Test _DecDefine._ParseItem
#
class DecDefineTestCase(unittest.TestCase):
    def GetObj(self, Content):
        Obj = _DecDefine(FileContent('dummy', Content.splitlines()))
        Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
        return Obj

    def testDecDefine(self):
        item = self.GetObj('PACKAGE_NAME = MdePkg')._ParseItem()
        self.assertEqual(item.Key, 'PACKAGE_NAME')
        self.assertEqual(item.Value, 'MdePkg')
    
    def testDecDefine1(self):
        obj = self.GetObj('PACKAGE_NAME')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testDecDefine2(self):
        obj = self.GetObj('unknown_key = ')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testDecDefine3(self):
        obj = self.GetObj('PACKAGE_NAME = ')
        self.assertRaises(FatalError, obj._ParseItem)

#
# Test _DecLibraryclass._ParseItem
#
class DecLibraryTestCase(unittest.TestCase):
    def GetObj(self, Content):
        Obj = _DecLibraryclass(FileContent('dummy', Content.splitlines()))
        Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
        return Obj
    
    def testNoInc(self):
        obj = self.GetObj('UefiRuntimeLib')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testEmpty(self):
        obj = self.GetObj(' | ')
        self.assertRaises(FatalError, obj._ParseItem)
        
    def testLibclassNaming(self):
        obj = self.GetObj('lowercase_efiRuntimeLib|Include/Library/UefiRuntimeLib.h')
        self.assertRaises(FatalError, obj._ParseItem)
        
    def testLibclassExt(self):
        obj = self.GetObj('RuntimeLib|Include/Library/UefiRuntimeLib.no_h')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testLibclassRelative(self):
        obj = self.GetObj('RuntimeLib|Include/../UefiRuntimeLib.h')
        self.assertRaises(FatalError, obj._ParseItem)

#
# Test _DecPcd._ParseItem
#
class DecPcdTestCase(unittest.TestCase):
    def GetObj(self, Content):
        Obj = _DecPcd(FileContent('dummy', Content.splitlines()))
        Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
        Obj._RawData.CurrentScope = [('PcdsFeatureFlag'.upper(), 'COMMON')]
        return Obj
    
    def testOK(self):
        item = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')._ParseItem()
        self.assertEqual(item.TokenSpaceGuidCName, 'gEfiMdePkgTokenSpaceGuid')
        self.assertEqual(item.TokenCName, 'PcdComponentNameDisable')
        self.assertEqual(item.DefaultValue, 'FALSE')
        self.assertEqual(item.DatumType, 'BOOLEAN')
        self.assertEqual(item.TokenValue, '0x0000000d')
    
    def testNoCvar(self):
        obj = self.GetObj('123ai.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testSplit(self):
        obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable FALSE|BOOLEAN|0x0000000d')
        self.assertRaises(FatalError, obj._ParseItem)
        
        obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|BOOLEAN|0x0000000d | abc')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testUnknownType(self):
        obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE|unknown|0x0000000d')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testVoid(self):
        obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|abc|VOID*|0x0000000d')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testUINT(self):
        obj = self.GetObj('gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|0xabc|UINT8|0x0000000d')
        self.assertRaises(FatalError, obj._ParseItem)

#
# Test _DecInclude._ParseItem
#
class DecIncludeTestCase(unittest.TestCase):
    #
    # Test code to be added
    #
    pass

#
# Test _DecGuid._ParseItem
#
class DecGuidTestCase(unittest.TestCase):
    def GetObj(self, Content):
        Obj = _DecGuid(FileContent('dummy', Content.splitlines()))
        Obj._RawData.CurrentLine = Obj._RawData.GetNextLine()
        Obj._RawData.CurrentScope = [('guids'.upper(), 'COMMON')]
        return Obj
    
    def testCValue(self):
        item = self.GetObj('gEfiIpSecProtocolGuid={ 0xdfb386f7, 0xe100, 0x43ad,'
                           ' {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')._ParseItem()
        self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid')
        self.assertEqual(item.GuidCValue, '{ 0xdfb386f7, 0xe100, 0x43ad, {0x9c, 0x9a, 0xed, 0x90, 0xd0, 0x8a, 0x5e, 0x12 }}')
    
    def testGuidString(self):
        item = self.GetObj('gEfiIpSecProtocolGuid=1E73767F-8F52-4603-AEB4-F29B510B6766')._ParseItem()
        self.assertEqual(item.GuidCName, 'gEfiIpSecProtocolGuid')
        self.assertEqual(item.GuidCValue, '1E73767F-8F52-4603-AEB4-F29B510B6766')
    
    def testNoValue1(self):
        obj = self.GetObj('gEfiIpSecProtocolGuid')
        self.assertRaises(FatalError, obj._ParseItem)
    
    def testNoValue2(self):
        obj = self.GetObj('gEfiIpSecProtocolGuid=')
        self.assertRaises(FatalError, obj._ParseItem)
        
    def testNoName(self):
        obj = self.GetObj('=')
        self.assertRaises(FatalError, obj._ParseItem)

#
# Test Dec.__init__
#
class DecDecInitTestCase(unittest.TestCase):
    def testNoDecFile(self):
        self.assertRaises(FatalError, Dec, 'No_Such_File')

class TmpFile:
    def __init__(self, File):
        self.File = File
    
    def Write(self, Content):
        try:
            FileObj = open(self.File, 'w')
            FileObj.write(Content)
            FileObj.close()
        except:
            pass
    
    def Remove(self):
        try:
            os.remove(self.File)
        except:
            pass

#
# Test Dec._UserExtentionSectionParser
#
class DecUESectionTestCase(unittest.TestCase):
    def setUp(self):
        self.File = TmpFile('test.dec')
        self.File.Write(
'''[userextensions.intel."myid"]
[userextensions.intel."myid".IA32]
[userextensions.intel."myid".IA32,]
[userextensions.intel."myid]
'''
        )
    
    def tearDown(self):
        self.File.Remove()
    
    def testUserExtentionHeader(self):
        dec = Dec('test.dec', False)
        
        # OK: [userextensions.intel."myid"]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        dec._UserExtentionSectionParser()
        self.assertEqual(len(dec._RawData.CurrentScope), 1)
        self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper())
        self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel')
        self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"')
        self.assertEqual(dec._RawData.CurrentScope[0][3], 'COMMON')
        
        # OK: [userextensions.intel."myid".IA32]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        dec._UserExtentionSectionParser()
        self.assertEqual(len(dec._RawData.CurrentScope), 1)
        self.assertEqual(dec._RawData.CurrentScope[0][0], 'userextensions'.upper())
        self.assertEqual(dec._RawData.CurrentScope[0][1], 'intel')
        self.assertEqual(dec._RawData.CurrentScope[0][2], '"myid"')
        self.assertEqual(dec._RawData.CurrentScope[0][3], 'IA32')
        
        # Fail: [userextensions.intel."myid".IA32,]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._UserExtentionSectionParser)
        
        # Fail: [userextensions.intel."myid]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._UserExtentionSectionParser)

#
# Test Dec._SectionHeaderParser
#
class DecSectionTestCase(unittest.TestCase):
    def setUp(self):
        self.File = TmpFile('test.dec')
        self.File.Write(
'''[no section start or end
[,] # empty sub-section
[unknow_section_name]
[Includes.IA32.other] # no third one
[PcdsFeatureFlag, PcdsFixedAtBuild] # feature flag PCD must not be in the same section of other types of PCD
[Includes.IA32, Includes.IA32]
[Includes, Includes.IA32] # common cannot be with other arch
[Includes.IA32, PcdsFeatureFlag] # different section name
'''     )
    
    def tearDown(self):
        self.File.Remove()
    
    def testSectionHeader(self):
        dec = Dec('test.dec', False)
        # [no section start or end
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        #[,] # empty sub-section
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        # [unknow_section_name]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        # [Includes.IA32.other] # no third one
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        # [PcdsFeatureFlag, PcdsFixedAtBuild]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        # [Includes.IA32, Includes.IA32]
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        dec._SectionHeaderParser()
        self.assertEqual(len(dec._RawData.CurrentScope), 1)
        self.assertEqual(dec._RawData.CurrentScope[0][0], 'Includes'.upper())
        self.assertEqual(dec._RawData.CurrentScope[0][1], 'IA32')
        
        # [Includes, Includes.IA32] # common cannot be with other arch
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)
        
        # [Includes.IA32, PcdsFeatureFlag] # different section name not allowed
        dec._RawData.CurrentLine = CleanString(dec._RawData.GetNextLine())[0]
        self.assertRaises(FatalError, dec._SectionHeaderParser)

#
# Test Dec._ParseDecComment
#
class DecDecCommentTestCase(unittest.TestCase):
    def testDecHeadComment(self):
        File = TmpFile('test.dec')
        File.Write(
       '''# abc
          ##''')
        dec = Dec('test.dec', False)
        dec.ParseDecComment()
        self.assertEqual(len(dec._HeadComment), 2)
        self.assertEqual(dec._HeadComment[0][0], '# abc')
        self.assertEqual(dec._HeadComment[0][1], 1)
        self.assertEqual(dec._HeadComment[1][0], '##')
        self.assertEqual(dec._HeadComment[1][1], 2)
        File.Remove()
    
    def testNoDoubleComment(self):
        File = TmpFile('test.dec')
        File.Write(
       '''# abc
          #
          [section_start]''')
        dec = Dec('test.dec', False)
        dec.ParseDecComment()
        self.assertEqual(len(dec._HeadComment), 2)
        self.assertEqual(dec._HeadComment[0][0], '# abc')
        self.assertEqual(dec._HeadComment[0][1], 1)
        self.assertEqual(dec._HeadComment[1][0], '#')
        self.assertEqual(dec._HeadComment[1][1], 2)
        File.Remove()

if __name__ == '__main__':
    import Logger.Logger
    Logger.Logger.Initialize()
    unittest.main()

