#!/usr/bin/python
"""
$Id: page_size.py,v 1.11 2006/12/01 09:45:39 dom Exp $

The PageSizeTestCase implements the validator.testcase.TestCase
interface for the tests related to the following BPs:
* Divide pages into usable but limited size portions.
* Ensure that the overall size of page is appropriate to the
  memory limitations of the device.

Relies on httplib2 for retrieval/caching
http://bitworking.org/projects/httplib2/

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 PAGE_SIZE_USABLE and PAGE_SIZE_LIMIT BP
class PageSizeTestCase(testcase.LinksBasedTestCase):
    BpId = ["PAGE_SIZE_USABLE","PAGE_SIZE_LIMIT"]

    def _getSize(self,uri):
        headers,content=self._http_request(uri)
        return len(content)
        
    
    def _observeLinks(self):
        # downloading page to see markup size
        size = self._getSize(self.uri)
        # @@@ this should be loaded from the profile
        if size > 10240:
            self.addObservation(Observation("PS1",testcase.Location(self.uri),{"markupsize":size}))

        from validator import utils
        links = self.getLinks()
        sizeEmbeddedResources = 0
        uris = []
        for link in links:
            if link.nature==utils.LINK_TYPE_EMBED and not link.target in uris:
                uris.append(link.target)
                if link.mime in ["image/jpeg","image/gif","text/css"]:
                    # @@@ Should only count once when there are imbricated objects
                    sizeEmbeddedResources = sizeEmbeddedResources + self._getSize(link.target)
        # @@@ this should be loaded from the profile                
        if size + sizeEmbeddedResources > 20480:
            self.addObservation(Observation("PS2",testcase.Location(self.uri),{"markupsize":size,"totalsize":size  + sizeEmbeddedResources }))
        if "PS1" not in self._observations and "PS2" not in self._observations:
            self.addObservation(Observation("PS3",testcase.Location(self.uri),{"markupsize":size,"totalsize":size  + sizeEmbeddedResources }))

                
# -------------------------
# 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 = PageSizeTestCase()
        self.assertEqual(a.run(inp),res)
    
    def testWithOKSize(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/base.xhtml"
        res = TestResults(
            [Observation("PS3",Location(inp),{'totalsize': 612, 'markupsize': 493})]
            )
        self._test(inp,res)

    def testWithTooBigMarkup(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/pagesize-1.xhtml"
        res = TestResults(
            [Observation("PS1",Location(inp),{'markupsize': 11128})]
            )
        self._test(inp,res)
        
    def testWithTooBigEmbed(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/pagesize-2.xhtml"
        res = TestResults(
            [Observation("PS2",Location(inp),{'totalsize': 22227,'markupsize': 860})]
            )
        self._test(inp,res)


def _test():
    unittest.main()

if __name__ == '__main__':
    _test()



