#!/usr/bin/python
"""
$Id: object_scripts.py,v 1.7 2007/04/26 07:22:29 dom Exp $

The ObjectScriptTestCase implements the validator.testcase.TestCase
interface for the tests related to the following BP:
* Do not rely on embedded objects or script.

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 OBJECT_OR_SCRIPTS BP
class ObjectScriptTestCase(testcase.LinksBasedTestCase):
    BpId = ["OBJECT_OR_SCRIPTS"]

    def startDocument(self):
        self._inObject = 0
        self._hasObjects = False
        self._supportedFallback = True
        
    def startElement(self, name, attrs):
        if name=="script":
            location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
            self.addObservation(testcase.Observation("OS1",location))
        elif name=="object":
            self._hasObjects = True
            location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
            if not self._inObject:
                self._objectFallbackText = ""
                self._objectContent = []
                self._objectSupportedContent = []
            self._inObject = self._inObject + 1
            if attrs.has_key("data"):
                uri = self._absolutize(attrs["data"])
                self._objectContent.append(uri)
                headers,content = self._http_request(uri)
                mime = self._getMimeType(headers)
                if mime in self._profile.getList("supportedEmbed","mime"):
                    self._objectSupportedContent.append(uri)
        elif name in ["a","area"] and attrs.has_key("href"):
            if  attrs["href"].split(":")[0]=="javascript":
                location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
                self.addObservation(testcase.Observation("OS3",location))

    def characters(self,content):
        if self._inObject:
            self._objectFallbackText = self._objectFallbackText + content

    def endElement(self,name):
        if name=="object":
            self._inObject = self._inObject - 1
            if self._inObject <= 0:
                if len(self._objectSupportedContent)==0:
                    location = testcase.LineColumnLocation(self.uri,self.getEncoding(),self.locator.getLineNumber(),self.locator.getColumnNumber())
                    self._supportedFallback = False
                    if self._objectFallbackText.strip()=="": 
                        self.addObservation(testcase.Observation("OS5",location))
                    # not clear how to interpret the FAIL in the
                    # current mobileOK basic draft
                else:
                    # do we need to say somewhere that all the objects have a fallback in a supported format?
                    pass
                        
                    
    
    def endDocument(self):
        if not "OS3" in self._observations:
            if not "OS1" in self._observations:
                if not self._hasObjects:
                    self.addObservation(testcase.Observation("OS2",testcase.Location(self.uri)))
                else:
                    self.addObservation(testcase.Observation("OS4",testcase.Location(self.uri)))
        if self._hasObjects:
            if self._supportedFallback:
                self.addObservation(testcase.Observation("OS7",testcase.Location(self.uri)))
            else:
                self.addObservation(testcase.Observation("OS6",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 = ObjectScriptTestCase()
        self.assertEqual(a.run(inp),res)

    def testWithNoObjectNorScripts(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/base.xhtml"
        res = TestResults(
            [Observation("OS2",Location(inp))]
            )
        self._test(inp,res)
    
    def testWithObject(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/nontext-2.xhtml"
        res = TestResults(
            [Observation("OS1",LineColumnLocation(inp,"utf-8",11,14))]
            )
        self._test(inp,res)

    def testWithScript(self):
        inp = "http://dev.w3.org/cvsweb/~checkout~/2006/mwbp-validator/tests/script.xhtml"
        res = TestResults(
            [Observation("OS1",LineColumnLocation(inp,"utf-8",11,0)),
             Observation('OS3',LineColumnLocation(inp,"utf-8",16,13))
             ]
            )
        self._test(inp,res)

def _test():
    unittest.main()

if __name__ == '__main__':
    _test()



