from __future__ import unicode_literals

import unittest
import os
import time
from os.path import join

from fs.opener import fsopendir
from moya.context import Context
from moya.template.moyatemplates import MoyaTemplateEngine
from moya.archive import Archive
from moya.settings import SettingsContainer


class TestTemplates(unittest.TestCase):
    def setUp(self):
        path = os.path.abspath(os.path.dirname(__file__))
        templates_path = join(path, "templates")
        self.fs = fsopendir(templates_path)
        self.archive = Archive()
        self.archive.init_cache("templates", SettingsContainer.create(type="dict"))
        self.archive.init_cache("fragment", SettingsContainer.create(type="dict"))
        self.engine = MoyaTemplateEngine(self.archive, self.fs, {})

    def tearDown(self):
        self.fs.close()
        self.fs = None
        self.archive = None
        self.engine = None

    def _render(self, *template_paths, **kwargs):
        return self.engine.render(template_paths, kwargs)

    def test_substitute(self):
        """Test template substitution"""
        tests = [
            (dict(fruit="apple"), "My favorite fruit is apple"),
            (dict(fruit="pear"), "My favorite fruit is pear"),
            (dict(), "My favorite fruit is ")
        ]
        for test_data, result in tests:
            html = self._render("simplesub.html", **test_data)
            self.assertEqual(result, html)

    def test_safe_substitute(self):
        """Test safe strings"""
        from moya.render import HTML
        html = self._render("simplesub.html", fruit="<em>oranges</em>")
        self.assertEqual(html, "My favorite fruit is &lt;em&gt;oranges&lt;/em&gt;")

        html = self._render("simplesub.html", fruit=HTML("<em>oranges</em>"))
        self.assertEqual(html, "My favorite fruit is <em>oranges</em>")

    def test_if(self):
        """Test template IF tag"""
        tests = [
            (dict(fruit="apple"), "I like apples"),
            (dict(fruit="pear"), "Pears are good"),
            (dict(), "I don't like fruit")
        ]
        for test_data, result in tests:
            html = self._render("if.html", **test_data)
            self.assertEqual(result, html)

    def test_for(self):
        """Test template FOR tag"""
        fruits = ["apples", "oranges", "carrot", "pears"]
        tests = [
            (dict(fruits=fruits), "I like apples, oranges, pears"),
            (dict(fruits=[]), "I don't like fruit"),
        ]
        for test_data, result in tests:
            html = self._render("for.html", **test_data)
            self.assertEqual(result, html)

    def test_escape(self):
        """Test HTML escaping"""
        tests = [
            (dict(text="Stuff & things"), "Stuff &amp; things"),
            (dict(text="<html>"), "&lt;html&gt;"),
        ]
        for test_data, result in tests:
            html = self._render("escape.html", **test_data)
            self.assertEqual(result, html)

    def test_extends(self):
        """Test extending templates"""
        html = self._render("extends.html", title="Hello")
        self.assertEqual(html, "<title>Hello</title>")

    def test_block(self):
        """Test extending templates"""
        html = self._render("extendsreplace.html")
        self.assertEqual(html, "B\n")
        html = self._render("extendsreplaceexplicit.html")
        self.assertEqual(html, "B\n")
        html = self._render("extendsappend.html")
        self.assertEqual(html, "A\nB\n")
        html = self._render("extendsprepend.html")
        self.assertEqual(html, "B\nA\n")

    def test_def(self):
        """Test def and call tags in templates"""
        html = self._render("def.html", fruit="apples")
        self.assertEqual("I like apples", html)

    def test_emit(self):
        """Test emit tag in template"""
        html = self._render("emit.html")
        self.assertEqual(html, "{% ${nosubstitute} %}")

    def test_comments(self):
        """Test template comments"""
        html = self._render("comment.html")
        self.assertEqual(html, "apples")
        html = self._render("comment2.html")
        self.assertEqual(html.splitlines()[0].rstrip(), "0 1  3")

    def test_empty(self):
        """Test empty template"""
        html = self._render("empty.html")
        self.assertEqual(html, "")

    def test_justtext(self):
        """Test plain text template"""
        html = self._render("justtext.html")
        self.assertEqual(html, "Just\nText")

    def test_verbatim(self):
        """Test verbatim tag"""
        html = self._render("verbatim.html")
        self.assertEqual("{% for fruit in fruits %}${fruit}{% endfor %}", html)

    def test_cache(self):
        """Test cache tag"""
        html = self._render("cache.html")
        result_html = "<ul><li>1</li><li>2</li><li>3</li></ul>"
        self.assertEqual(html, result_html)
        # A second time so it is read from the cache
        html = self._render("cache.html")
        result_html = "<ul><li>1</li><li>2</li><li>3</li></ul>"
        self.assertEqual(html, result_html)
        # Sleep so the key expires
        time.sleep(.1)
        # Check it once more
        html = self._render("cache.html")
        result_html = "<ul><li>1</li><li>2</li><li>3</li></ul>"
        self.assertEqual(html, result_html)

    def test_whitespace(self):
        """Test syntax for whitespace removal"""
        html = self._render("whitespace.html")
        self.assertEqual(html, "12345")
