#!/usr/bin/python
"""
$Id: scrolling.py,v 1.10 2006/11/15 10:50:35 dom Exp $

The ScrollingTestCase implements the validator.testcase.TestCase
interface for the tests related to the following BP:
* Limit scrolling to one direction, unless secondary scrolling
  cannot be avoided.

License
-------
Copyright (c) 2006 World Wide Web Consortium, (Massachusetts
Institute of Technology, European Research Consortium for Informatics
and Mathematics, Keio University). All Rights Reserved. This work is
distributed under the W3C Software License [1] in the hope that it
will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[1] http://www.w3.org/Consortium/Legal/copyright-software

"""



from  validator import testcase

# Tests regarding the SCROLLING BP
class ScrollingTestCase(testcase.XMLBasedTestCase):
    BpId = ["SCROLLING"]

    def startDocument(self):
        self._currentTableDefaultWidth = 0
        self._currentRowWidth = 0
        self._defaultCellWidth = 0
        self._maxCurrentTableWidth = 0

    

    def startElement(self,name,attrs):
        def _getAttributeValue(attr):
            if attrs.has_key(attr):
                if not "%" in attrs[attr]:
                    try:
                        return int(attrs[attr])
                    except:
                        return 0
                else:
                    return 0
            else:
                return 0
            
        if name=="table":
            location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
            self._maxCurrentTableWidth = 0
            self._currentTableDefaultWidth = 0
            self._defaultCellWidth = 0
            if  _getAttributeValue("width") + _getAttributeValue("border") > 120:
                self.addObservation(Observation("SC1",location,{"width":_getAttributeValue("width") + _getAttributeValue("border")}))
            self._currentTableDefaultWidth = _getAttributeValue("border") + _getAttributeValue("cellspacing")
            self._currentRowWidth = self._currentTableDefaultWidth
            cellborder = 0
            if _getAttributeValue("border"):
                cellborder = 1
            self._defaultCellWidth = cellborder + _getAttributeValue("cellpadding")*2 + _getAttributeValue("cellspacing")
        elif name=="tr":
            self._currentRowWidth = self._currentTableDefaultWidth
        elif name=="td" or name=="th":
            self._currentRowWidth = self._currentRowWidth + self._defaultCellWidth + _getAttributeValue("width")
        elif name in ["img","object","hr"] and attrs.has_key("width"):
            if "%" not in attrs["width"]:
                location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
                try:
                    # @@@ 120 should come from DDC profile
                    if int(attrs["width"])>120:
                        self.addObservation(Observation("SC1",location,{"width":attrs["width"]}))
                except ValueError:
                    self.addObservation(Observation("LE1",location,{"attribute":"width","value":attrs["width"],"expected":"a number or percents"}))


    def endElement(self,name):
        if name=="table":
            location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
            if self._maxCurrentTableWidth > 120:
                self.addObservation(Observation("SC1",location,{"width":self._maxCurrentTableWidth}))
        elif name=="tr":
            self._maxCurrentTableWidth = max(self._maxCurrentTableWidth,self._currentRowWidth)
        
    def endDocument(self):
        if "SC1" not in self._observations:
            self.addObservation(Observation("SC2",testcase.Location(self.uri)))

                
# -------------------------
# Unit tests for this module
import unittest

from validator.testcase import TestResults, Observation, Location, LineColumnLocation
class Tests(unittest.TestCase):
    def _test(self,inp,res):
        a = ScrollingTestCase()
        self.assertEqual(a.run(inp),res)
    
    def testWithNoScrolling(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/base.xhtml"
        res = TestResults(
            [Observation("SC2",Location(inp))]
            )
        self._test(inp,res)

    def testWithScrolling(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/scrolling-1.xhtml"
        res = TestResults(
            [Observation("SC1",LineColumnLocation(inp,'utf-8',9,3),{"width":"315"})]
            )
        self._test(inp,res)

    def testWithTableScrolling(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/scrolling-2.xhtml"
        res = TestResults(
            [Observation("SC1",LineColumnLocation(inp,'utf-8',14,0),{"width":189})]
            )
        self._test(inp,res)
        

def _test():
    unittest.main()

if __name__ == '__main__':
    _test()



