# Copyright (C) 2010 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""Unit tests for update_webgl_conformance_tests."""

import unittest
from webkitpy.to_be_moved import update_webgl_conformance_tests as webgl


def construct_script(name):
    return "<script src=\"" + name + "\"></script>\n"


def construct_style(name):
    return "<link rel=\"stylesheet\" href=\"" + name + "\">"


class TestTranslation(unittest.TestCase):
    def assert_unchanged(self, text):
        self.assertEqual(text, webgl.translate_khronos_test(text))

    def assert_translate(self, input, output):
        self.assertEqual(output, webgl.translate_khronos_test(input))

    def test_simple_unchanged(self):
        self.assert_unchanged("")
        self.assert_unchanged("<html></html>")

    def test_header_strip(self):
        single_line_header = "<!-- single line header. -->"
        multi_line_header = """<!-- this is a multi-line
                header.  it should all be removed too.
                -->"""
        text = "<html></html>"
        self.assert_translate(single_line_header, "")
        self.assert_translate(single_line_header + text, text)
        self.assert_translate(multi_line_header + text, text)

    def dont_strip_other_headers(self):
        self.assert_unchanged("<html>\n<!-- don't remove comments on other lines. -->\n</html>")

    def test_include_rewriting(self):
        # Mappings to None are unchanged
        styles = {
            "fail.css": None,
            "resources/stylesheet.css": None,
            "../resources/style.css": None,
        }
        scripts = {
            "../resources/js-test-pre.js": "../../../resources/js-test-pre.js",
            "../resources/js-test-post.js": "../../../resources/js-test-post.js",
            "../resources/desktop-gl-constants.js": "resources/desktop-gl-constants.js",

            "resources/shadow-offset.js": None,
            "../resources/js-test-post-async.js": None,
        }

        input_text = ""
        output_text = ""
        for input, output in styles.items():
            input_text += construct_style(input)
            output_text += construct_style(output if output else input)
        for input, output in scripts.items():
            input_text += construct_script(input)
            output_text += construct_script(output if output else input)

        head = '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">\n<html>\n<head>\n'
        foot = '</head>\n<body>\n</body>\n</html>'
        input_text = head + input_text + foot
        output_text = head + output_text + foot
        self.assert_translate(input_text, output_text)
