diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
new file mode 100644
index 0000000..e446ad8
--- /dev/null
+++ b/.github/workflows/python-app.yml
@@ -0,0 +1,48 @@
+name: collective.handlebars CI
+on: [push]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: [3.8, 3.7, 2.7]
+ plone-version: [5.2, 5.1]
+ exclude:
+ - python-version: 3.8
+ plone-version: 5.1
+ - python-version: 3.7
+ plone-version: 5.1
+ steps:
+ # git checkout
+ - uses: actions/checkout@v2
+
+ # python setup
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v1
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ # python cache
+ - uses: actions/cache@v1
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+
+ # python install
+ - name: pip install
+ run: pip install -r requirements.txt
+
+ # buildout
+ - name: buildout
+ run: buildout -t 10 -c plone-${{ matrix.plone-version }}.x.cfg code-analysis:return-status-codes=True
+
+ # code analysis
+ - name: code analysis
+ run: bin/code-analysis
+
+ # test
+ - name: test
+ run: bin/coverage run bin/test
diff --git a/.gitignore b/.gitignore
index a7f46ca..18115ae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,5 @@ report.html
.*.cfg
.Python
Pipfile*
+.idea
+pyvenv.cfg
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index abf4678..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-language: python
-sudo: false
-cache:
- directories:
- - eggs
-python:
- - 2.7.13
-env:
- - PLONE_VERSION=5.0
- - PLONE_VERSION=5.1
-before_install:
- - pip install -r requirements.txt
-install:
- - sed -ie "s#test-5.1#test-$PLONE_VERSION#" buildout.cfg
- - buildout annotate
- - buildout
-script:
- - bin/code-analysis
- - bin/coverage run bin/test
-after_success:
- - bin/coveralls
-notifications:
- email:
- - itconsense@gmail.com
diff --git a/CHANGES.rst b/CHANGES.rst
index c9e7006..e135c86 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,17 +2,29 @@ Changelog
=========
-1.5 (unreleased)
+1.6 (unreleased)
----------------
- Nothing changed yet.
+1.5 (2021-08-28)
+----------------
+
+- Python 3 / Plone 5.2 compatibility
+ [adrianschulz, tomgross]
+
+- Update dependencies
+- Move to Github CI
+- Apply black formatting
+ [tomgross]
+
+
1.4.1 (2018-10-22)
------------------
- Add div-element to wrapper to support cases where only text is provided
- (otherwise plone.protect can fail)
+ (otherwise plone.protect can fail)
[tomgross]
1.4 (2018-09-10)
diff --git a/MANIFEST.in b/MANIFEST.in
index 07a60db..7b09c3e 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
graft src/collective
graft docs
-include *.rst
+include *.rst *.txt
global-exclude *.pyc
diff --git a/buildout.cfg b/buildout.cfg
index 66b232f..cc47c72 100644
--- a/buildout.cfg
+++ b/buildout.cfg
@@ -1,5 +1,7 @@
[buildout]
-extends = https://raw.github.com/collective/buildout.plonetest/master/test-5.1.x.cfg
+extends =
+ https://raw.github.com/collective/buildout.plonetest/master/test-5.2.x.cfg
+ versions.cfg
package-name = collective.handlebars
package-extras = [test]
parts +=
@@ -26,29 +28,4 @@ flake8-extensions =
flake8-coding
-[versions]
-# Don't use a released version of collective.handlebars
-collective.handlebars =
-PyMeta3 = 0.5.1
-PyYAML = 3.13
-chardet = 3.0.4
-check-manifest = 0.37
-configparser = 3.5.0
-coverage = 4.0.3
-flake8 = 3.0.4
-flake8-blind-except = 0.1.1
-flake8-coding = 1.3.1
-flake8-debugger = 1.4.0
-idna = 2.6
-mccabe = 0.5.3
-plone.recipe.codeanalysis = 3.0.1
-plone.recipe.zope2instance = 4.4.0
-plone.testing = 5.0.0
-pybars3 = 0.9.6
-pycodestyle = 2.0.0
-pyflakes = 1.2.3
-python-coveralls = 2.7.0
-setuptools = 33.1.1
-sh = 1.12.14
-zc.buildout = 2.12.2
-zc.recipe.egg = 2.0.6
+
diff --git a/plone-5.1.x.cfg b/plone-5.1.x.cfg
new file mode 100644
index 0000000..af492e8
--- /dev/null
+++ b/plone-5.1.x.cfg
@@ -0,0 +1,32 @@
+[buildout]
+extends =
+ https://raw.github.com/collective/buildout.plonetest/master/test-5.1.x.cfg
+ versions.cfg
+package-name = collective.handlebars
+package-extras = [test]
+parts +=
+ coverage
+ code-analysis
+
+
+[coverage]
+recipe = zc.recipe.egg
+eggs =
+ ${test:eggs}
+ coverage
+ python-coveralls
+
+
+[code-analysis]
+recipe = plone.recipe.codeanalysis
+directory = ${buildout:directory}/src/collective
+flake8-exclude = bootstrap.py,bootstrap-buildout.py,docs,*.egg.,omelette
+flake8-max-complexity = 15
+flake8-extensions =
+ flake8-blind-except
+ flake8-debugger
+ flake8-coding
+
+[versions]
+plone.testing = 5.0.0
+six = 1.16.0
diff --git a/plone-5.2.x.cfg b/plone-5.2.x.cfg
new file mode 100644
index 0000000..0628f9b
--- /dev/null
+++ b/plone-5.2.x.cfg
@@ -0,0 +1,28 @@
+[buildout]
+extends =
+ https://raw.github.com/collective/buildout.plonetest/master/test-5.2.x.cfg
+ versions.cfg
+package-name = collective.handlebars
+package-extras = [test]
+parts +=
+ coverage
+ code-analysis
+
+
+[coverage]
+recipe = zc.recipe.egg
+eggs =
+ ${test:eggs}
+ coverage
+ python-coveralls
+
+
+[code-analysis]
+recipe = plone.recipe.codeanalysis
+directory = ${buildout:directory}/src/collective
+flake8-exclude = bootstrap.py,bootstrap-buildout.py,docs,*.egg.,omelette
+flake8-max-complexity = 15
+flake8-extensions =
+ flake8-blind-except
+ flake8-debugger
+ flake8-coding
diff --git a/requirements.txt b/requirements.txt
index c16b9b0..760259f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
-setuptools==33.1.1
-zc.buildout==2.12.2
+setuptools==42.0.2
+zc.buildout==2.13.4
+wheel
diff --git a/setup.py b/setup.py
index 455e5bf..4c8e696 100644
--- a/setup.py
+++ b/setup.py
@@ -14,19 +14,22 @@
setup(
name='collective.handlebars',
- version='1.5.dev0',
+ version='1.6.dev0',
description="Handlebars for Plone",
long_description=long_description,
# Get more from https://pypi.python.org/pypi?%3Aaction=list_classifiers
classifiers=[
"Environment :: Web Environment",
"Framework :: Plone",
- "Framework :: Plone :: 5.0",
"Framework :: Plone :: 5.1",
+ "Framework :: Plone :: 5.2",
"Programming Language :: Python",
"Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
"Operating System :: OS Independent",
"License :: OSI Approved :: GNU General Public License v2 (GPLv2)",
+ "Development Status :: 5 - Production/Stable"
],
keywords='Python Plone',
author='Tom Gross',
@@ -43,6 +46,7 @@
'Products.GenericSetup>=1.8.2',
'setuptools',
'pybars3',
+ 'six'
],
extras_require={
'test': [
diff --git a/src/collective/__init__.py b/src/collective/__init__.py
index 68c04af..03d08ff 100644
--- a/src/collective/__init__.py
+++ b/src/collective/__init__.py
@@ -1,2 +1,2 @@
# -*- coding: utf-8 -*-
-__import__('pkg_resources').declare_namespace(__name__)
+__import__("pkg_resources").declare_namespace(__name__)
diff --git a/src/collective/handlebars/__init__.py b/src/collective/handlebars/__init__.py
index 831813c..78d73ef 100644
--- a/src/collective/handlebars/__init__.py
+++ b/src/collective/handlebars/__init__.py
@@ -3,4 +3,4 @@
from zope.i18nmessageid import MessageFactory
-_ = MessageFactory('collective.handlebars')
+_ = MessageFactory("collective.handlebars")
diff --git a/src/collective/handlebars/browser/views.py b/src/collective/handlebars/browser/views.py
index ccb0622..9fd76f7 100644
--- a/src/collective/handlebars/browser/views.py
+++ b/src/collective/handlebars/browser/views.py
@@ -9,16 +9,21 @@
from zope.i18n import translate
import os.path
+import six
import sys
try:
- get_distribution('plone.tiles')
-except DistributionNotFound: # pragma: no cover
+ get_distribution("plone.tiles")
+except DistributionNotFound: # pragma: no cover
+
class Tile(BrowserView):
"""Fake Tile which is only a BrowserView"""
+
class PersistentTile(BrowserView):
"""Fake persistent Tile which is only a BrowserView"""
-else: # pragma: no cover
+
+
+else: # pragma: no cover
from plone.tiles.tile import Tile
from plone.tiles.tile import PersistentTile
@@ -34,9 +39,8 @@ def package_home(gdict):
class HandlebarsMixin:
-
def get_contents(self):
- """ Get CMS data and put it in a JSON format for hbs inclusion
+ """Get CMS data and put it in a JSON format for hbs inclusion
:return: dictonary (must not be a JSON structure!
The conversion is handled by the templating engine)
@@ -63,13 +67,13 @@ def _get_hbs_template(self, hbs_filename):
compiled_template = HBS_REGISTRY[hbs_filename]
else:
with open(hbs_filename) as f:
- hbs_template = unicode(f.read(), 'utf-8')
- compiled_template = compiler.compile(hbs_template)
- HBS_REGISTRY[hbs_filename] = compiled_template
+ hbs_template = six.ensure_text(f.read())
+ compiled_template = compiler.compile(hbs_template)
+ HBS_REGISTRY[hbs_filename] = compiled_template
return compiled_template
def get_partials(self, hbs_dir):
- """ Get partials for rendering the master hbs_template
+ """Get partials for rendering the master hbs_template
:param hbs_dir: directory of master template
(/home/vagrant/templates/)
@@ -79,7 +83,7 @@ def get_partials(self, hbs_dir):
return {}
def get_helpers(self):
- """ Get helpers for rendering the master hbs_template
+ """Get helpers for rendering the master hbs_template
:return: dictonary with compiled partials templates
({'list': self.list_items()})
@@ -92,25 +96,26 @@ def hbs_snippet(self, filename=None, _prefix=None):
path = self.get_path_from_prefix(_prefix)
hbs_file = os.path.join(path, filename)
if not os.path.isfile(hbs_file):
- raise ValueError('No such file', hbs_file)
- elif hasattr(self, 'index'): # noqa
+ raise ValueError("No such file", hbs_file)
+ elif hasattr(self, "index"): # noqa
# second scenario: get snippet from zcml
# reuse filename from tile definition in zcml but read file here
# otherwise it is interpreted as XML/PT
hbs_file = self.index.filename
else:
- raise ValueError('No template found!')
+ raise ValueError("No template found!")
hbs_template = self._get_hbs_template(hbs_file)
hbs_dir = os.path.dirname(hbs_file)
partials = self.get_partials(hbs_dir)
helpers = self.get_helpers()
- self.request.response.setHeader("Content-type",
- "text/html; charset=utf-8")
- return hbs_template(self.get_contents(),
- helpers=helpers,
- partials=partials)
+ self.request.response.setHeader(
+ "Content-type", "text/html; charset=utf-8"
+ )
+ return hbs_template(
+ self.get_contents(), helpers=helpers, partials=partials
+ )
def get_path_from_prefix(self, _prefix):
if isinstance(_prefix, str):
@@ -121,42 +126,51 @@ def get_path_from_prefix(self, _prefix):
path = package_home(_prefix)
return path
- def translate(self, msgid, domain=None, mapping=None, context=None,
- target_language=None, default=None):
+ def translate(
+ self,
+ msgid,
+ domain=None,
+ mapping=None,
+ context=None,
+ target_language=None,
+ default=None,
+ ):
if not target_language:
target_language = api.portal.get_current_language(context)
- return translate(msgid=msgid,
- domain=domain,
- mapping=mapping,
- context=context,
- default=default,
- target_language=target_language)
+ return translate(
+ msgid=msgid,
+ domain=domain,
+ mapping=mapping,
+ context=context,
+ default=default,
+ target_language=target_language,
+ )
def _wrap_widget(self, render):
- if render and render.startswith(u'
'):
+ if render and render.startswith(u""):
return render
- return ''.join([u'', render, u'
'])
+ return "".join([u"", render, u"
"])
class HandlebarsBrowserView(BrowserView, HandlebarsMixin):
- """ A simple browserview using hbs as templating engine"""
+ """A simple browserview using hbs as templating engine"""
def __call__(self, *args, **kwargs):
return self.hbs_snippet()
class HandlebarsPloneView(BrowserView, HandlebarsMixin):
- """ A hbs view rendered in the content slot of the main template of Plone
- """
+ """A hbs view rendered in the content slot of the main template of Plone"""
- main_template = ViewPageTemplateFile('templates/plone_standard_template.pt') # noqa
+ main_template = ViewPageTemplateFile(
+ "templates/plone_standard_template.pt"
+ )
def __call__(self, *args, **kwargs):
return self.main_template(*args, **kwargs)
class HandlebarsTile(Tile, HandlebarsMixin):
-
def __call__(self, *args, **kwargs):
return self._wrap_widget(self.hbs_snippet())
@@ -166,8 +180,8 @@ def __call__(self, *args, **kwargs):
class HandlebarsPersistentTile(PersistentTile, HandlebarsMixin):
-
def __call__(self, *args, **kwargs):
return self._wrap_widget(self.hbs_snippet())
+
# EOF
diff --git a/src/collective/handlebars/setuphandlers.py b/src/collective/handlebars/setuphandlers.py
index 625480b..1ff7ad6 100644
--- a/src/collective/handlebars/setuphandlers.py
+++ b/src/collective/handlebars/setuphandlers.py
@@ -5,12 +5,11 @@
@implementer(INonInstallable)
class HiddenProfiles(object):
-
def getNonInstallableProfiles(self):
"""Hide uninstall profile from site-creation and quickinstaller"""
return [
- 'collective.handlebars:default',
- 'collective.handlebars:uninstall',
+ "collective.handlebars:default",
+ "collective.handlebars:uninstall",
]
diff --git a/src/collective/handlebars/testing.py b/src/collective/handlebars/testing.py
index 45f60e3..ea4f152 100644
--- a/src/collective/handlebars/testing.py
+++ b/src/collective/handlebars/testing.py
@@ -2,12 +2,10 @@
from collective.handlebars.browser.views import HandlebarsBrowserView
from collective.handlebars.browser.views import HandlebarsPloneView
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
-from plone.app.robotframework.testing import REMOTE_LIBRARY_BUNDLE_FIXTURE
from plone.app.testing import applyProfile
from plone.app.testing import FunctionalTesting
from plone.app.testing import IntegrationTesting
from plone.app.testing import PloneSandboxLayer
-from plone.testing import z2
import collective.handlebars
@@ -21,23 +19,23 @@ def setUpZope(self, app, configurationContext):
# The z3c.autoinclude feature is disabled in the Plone fixture base
# layer.
self.loadZCML(package=collective.handlebars)
- self.loadZCML(package=collective.handlebars, name='testing.zcml')
+ self.loadZCML(package=collective.handlebars, name="testing.zcml")
def setUpPloneSite(self, portal):
- applyProfile(portal, 'collective.handlebars:default')
+ applyProfile(portal, "collective.handlebars:default")
class HBSTestView(HandlebarsBrowserView):
-
def get_contents(self):
- return {'title': u'Fäncy Title', 'body': u'This is the body'}
+ return {"title": u"Fäncy Title", "body": u"This is the body"}
class HBSTestPloneView(HandlebarsPloneView):
-
def get_contents(self):
- return {'title': u'Fäncy Title',
- 'body': u'This is the Plone View body'}
+ return {
+ "title": u"Fäncy Title",
+ "body": u"This is the Plone View body",
+ }
COLLECTIVE_HANDLEBARS_FIXTURE = CollectiveHandlebarsLayer()
@@ -45,21 +43,11 @@ def get_contents(self):
COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING = IntegrationTesting(
bases=(COLLECTIVE_HANDLEBARS_FIXTURE,),
- name='CollectiveHandlebarsLayer:IntegrationTesting'
+ name="CollectiveHandlebarsLayer:IntegrationTesting",
)
COLLECTIVE_HANDLEBARS_FUNCTIONAL_TESTING = FunctionalTesting(
bases=(COLLECTIVE_HANDLEBARS_FIXTURE,),
- name='CollectiveHandlebarsLayer:FunctionalTesting'
-)
-
-
-COLLECTIVE_HANDLEBARS_ACCEPTANCE_TESTING = FunctionalTesting(
- bases=(
- COLLECTIVE_HANDLEBARS_FIXTURE,
- REMOTE_LIBRARY_BUNDLE_FIXTURE,
- z2.ZSERVER_FIXTURE
- ),
- name='CollectiveHandlebarsLayer:AcceptanceTesting'
+ name="CollectiveHandlebarsLayer:FunctionalTesting",
)
diff --git a/src/collective/handlebars/tests/robot/test_example.robot b/src/collective/handlebars/tests/robot/test_example.robot
deleted file mode 100644
index dde1662..0000000
--- a/src/collective/handlebars/tests/robot/test_example.robot
+++ /dev/null
@@ -1,66 +0,0 @@
-# ============================================================================
-# EXAMPLE ROBOT TESTS
-# ============================================================================
-#
-# Run this robot test stand-alone:
-#
-# $ bin/test -s collective.handlebars -t test_example.robot --all
-#
-# Run this robot test with robot server (which is faster):
-#
-# 1) Start robot server:
-#
-# $ bin/robot-server --reload-path src collective.handlebars.testing.COLLECTIVE_HANDLEBARS_ACCEPTANCE_TESTING
-#
-# 2) Run robot tests:
-#
-# $ bin/robot src/collective/handlebars/tests/robot/test_example.robot
-#
-# See the http://docs.plone.org for further details (search for robot
-# framework).
-#
-# ============================================================================
-
-*** Settings *****************************************************************
-
-Resource plone/app/robotframework/selenium.robot
-Resource plone/app/robotframework/keywords.robot
-
-Library Remote ${PLONE_URL}/RobotRemote
-
-Test Setup Open test browser
-Test Teardown Close all browsers
-
-
-*** Test Cases ***************************************************************
-
-Scenario: As a member I want to be able to log into the website
- [Documentation] Example of a BDD-style (Behavior-driven development) test.
- Given a login form
- When I enter valid credentials
- Then I am logged in
-
-
-*** Keywords *****************************************************************
-
-# --- Given ------------------------------------------------------------------
-
-a login form
- Go To ${PLONE_URL}/login_form
- Wait until page contains Login Name
- Wait until page contains Password
-
-
-# --- WHEN -------------------------------------------------------------------
-
-I enter valid credentials
- Input Text __ac_name admin
- Input Text __ac_password secret
- Click Button Log in
-
-
-# --- THEN -------------------------------------------------------------------
-
-I am logged in
- Wait until page contains You are now logged in
- Page should contain You are now logged in
diff --git a/src/collective/handlebars/tests/test_robot.py b/src/collective/handlebars/tests/test_robot.py
deleted file mode 100644
index f83b9fc..0000000
--- a/src/collective/handlebars/tests/test_robot.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# -*- coding: utf-8 -*-
-from collective.handlebars.testing import COLLECTIVE_HANDLEBARS_ACCEPTANCE_TESTING # noqa
-from plone.app.testing import ROBOT_TEST_LEVEL
-from plone.testing import layered
-
-import os
-import robotsuite
-import unittest
-
-
-def test_suite():
- suite = unittest.TestSuite()
- current_dir = os.path.abspath(os.path.dirname(__file__))
- robot_dir = os.path.join(current_dir, 'robot')
- robot_tests = [
- os.path.join('robot', doc) for doc in os.listdir(robot_dir)
- if doc.endswith('.robot') and doc.startswith('test_')
- ]
- for robot_test in robot_tests:
- robottestsuite = robotsuite.RobotTestSuite(robot_test)
- robottestsuite.level = ROBOT_TEST_LEVEL
- suite.addTests([
- layered(
- robottestsuite,
- layer=COLLECTIVE_HANDLEBARS_ACCEPTANCE_TESTING
- ),
- ])
- return suite
diff --git a/src/collective/handlebars/tests/test_setup.py b/src/collective/handlebars/tests/test_setup.py
index 195d137..1cab495 100644
--- a/src/collective/handlebars/tests/test_setup.py
+++ b/src/collective/handlebars/tests/test_setup.py
@@ -1,11 +1,29 @@
# -*- coding: utf-8 -*-
"""Setup tests for this package."""
-from collective.handlebars.testing import COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING # noqa
+from collective.handlebars.testing import (
+ COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING,
+)
from plone import api
import unittest
+try:
+ from Products.CMFPlone.utils import get_installer
+except ImportError: # pragma: no cover
+ # Quick shim for 5.1 api change
+
+ class get_installer(object): # noqa
+ def __init__(self, portal, request): # noqa
+ self.installer = api.portal.get_tool(name="portal_quickinstaller")
+
+ def is_product_installed(self, name):
+ return self.installer.isProductInstalled(name)
+
+ def uninstall_product(self, name):
+ return self.installer.uninstallProducts([name])
+
+
class TestSetup(unittest.TestCase):
"""Test that collective.handlebars is properly installed."""
@@ -13,19 +31,20 @@ class TestSetup(unittest.TestCase):
def setUp(self):
"""Custom shared utility setup for tests."""
- self.portal = self.layer['portal']
- self.installer = api.portal.get_tool('portal_quickinstaller')
+ self.portal = self.layer["portal"]
+ self.installer = get_installer(self.portal, self.layer["request"])
def test_product_installed(self):
"""Test if collective.handlebars is installed."""
- self.assertTrue(self.installer.isProductInstalled(
- 'collective.handlebars'))
+ self.assertTrue(
+ self.installer.is_product_installed("collective.handlebars")
+ )
def test_browserlayer(self):
"""Test that ICollectiveHandlebarsLayer is registered."""
- from collective.handlebars.interfaces import (
- ICollectiveHandlebarsLayer)
+ from collective.handlebars.interfaces import ICollectiveHandlebarsLayer
from plone.browserlayer import utils
+
self.assertIn(ICollectiveHandlebarsLayer, utils.registered_layers())
@@ -34,27 +53,34 @@ class TestUninstall(unittest.TestCase):
layer = COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING
def setUp(self):
- self.portal = self.layer['portal']
- self.installer = api.portal.get_tool('portal_quickinstaller')
- self.installer.uninstallProducts(['collective.handlebars'])
+ self.portal = self.layer["portal"]
+ self.installer = get_installer(self.portal, self.layer["request"])
+ self.installer.uninstall_product("collective.handlebars")
def test_product_uninstalled(self):
"""Test if collective.handlebars is cleanly uninstalled."""
- self.assertFalse(self.installer.isProductInstalled(
- 'collective.handlebars'))
+ self.assertFalse(
+ self.installer.is_product_installed("collective.handlebars")
+ )
def test_browserlayer_removed(self):
"""Test that ICollectiveHandlebarsLayer is removed."""
from collective.handlebars.interfaces import ICollectiveHandlebarsLayer
from plone.browserlayer import utils
+
self.assertNotIn(ICollectiveHandlebarsLayer, utils.registered_layers())
def test_hiddenprofiles(self):
- """ Test uninstall profile is hidden
+ """Test uninstall profile is hidden
:return:None
"""
from collective.handlebars.setuphandlers import HiddenProfiles
- self.assertIn('collective.handlebars:default',
- HiddenProfiles().getNonInstallableProfiles())
- self.assertIn('collective.handlebars:uninstall',
- HiddenProfiles().getNonInstallableProfiles())
+
+ self.assertIn(
+ "collective.handlebars:default",
+ HiddenProfiles().getNonInstallableProfiles(),
+ )
+ self.assertIn(
+ "collective.handlebars:uninstall",
+ HiddenProfiles().getNonInstallableProfiles(),
+ )
diff --git a/src/collective/handlebars/tests/test_views.py b/src/collective/handlebars/tests/test_views.py
index 3b5e41d..9a8b3a5 100644
--- a/src/collective/handlebars/tests/test_views.py
+++ b/src/collective/handlebars/tests/test_views.py
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
"""Setup tests for this package."""
-from collective.handlebars.testing import COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING # noqa
+from collective.handlebars.testing import (
+ COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING,
+)
from collective.handlebars.browser.views import HandlebarsBrowserView
from collective.handlebars.browser.views import HandlebarsTile
from collective.handlebars.browser.views import HandlebarsPersistentTile
@@ -9,72 +11,66 @@
from zope.i18nmessageid import MessageFactory
from zope import component, interface
from zope.i18n.interfaces import ITranslationDomain
-import os.path
+import os.path
+import six
import unittest
-TEST_DATA__DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),
- 'data')
-_ = MessageFactory('my.domain')
+TEST_DATA__DIR = os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), "data"
+)
+_ = MessageFactory("my.domain")
def normalize(stream):
- return ' '.join([snippet.strip() for snippet in stream.split()])
+ return " ".join([snippet.strip() for snippet in stream.split()])
class DummyHbsTile(HandlebarsTile):
-
def get_contents(self):
- return {'src': 'foo', 'alt': 'bar'}
+ return {"src": "foo", "alt": "bar"}
class DummyHbsPersistentTile(HandlebarsPersistentTile):
-
def get_contents(self):
- return {'src': 'foo', 'alt': 'bar'}
+ return {"src": "foo", "alt": "bar"}
class DummyHbsTemplate(object):
-
def __init__(self, filename):
self.filename = filename
@interface.implementer(ITranslationDomain)
class TestDomain(dict):
-
def translate(self, text, *_, **__):
return self[text], _[2]
class DummyHbsFile(HandlebarsBrowserView):
-
def get_contents(self):
- return {'title': u'File Test',
- 'body': u'Hello HBS World!'}
+ return {"title": u"File Test", "body": u"Hello HBS World!"}
def __call__(self):
- return self.hbs_snippet('data/minimal.hbs')
+ return self.hbs_snippet("data/minimal.hbs")
def invalid(self):
- return self.hbs_snippet('data/minimal_notfound.hbs')
+ return self.hbs_snippet("data/minimal_notfound.hbs")
class HelperHbsView(HandlebarsBrowserView):
-
def get_contents(self):
- return {'title': u'File Test',
- 'body': u'Hello HBS Wörld!'}
+ return {"title": u"File Test", "body": u"Hello HBS Wörld!"}
def _myhelper(self, options, items):
- return u'HELPER: ' + items
+ return u"HELPER: " + items
def get_helpers(self):
- return {'myhelper': self._myhelper}
+ return {"myhelper": self._myhelper}
def __call__(self):
- return self.hbs_snippet('data/helper.hbs')
+ return self.hbs_snippet("data/helper.hbs")
class TestBrowserView(unittest.TestCase):
@@ -84,64 +80,73 @@ class TestBrowserView(unittest.TestCase):
def setUp(self):
"""Custom shared utility setup for tests."""
- self.portal = self.layer['portal']
- self.view = self.portal.restrictedTraverse('@@hbs_test_view')
+ self.portal = self.layer["portal"]
+ self.view = self.portal.restrictedTraverse("@@hbs_test_view")
def test_get_contents_default(self):
- """ Method `get_tile_data` is not implemented in base class
+ """Method `get_tile_data` is not implemented in base class
:return:
"""
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
self.assertRaises(NotImplementedError, view.get_contents)
def test_base_view(self):
- """ An error is raised, if no template is specified """
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
+ """An error is raised, if no template is specified"""
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
self.assertRaises(ValueError, view)
def test_example_view(self):
"""Test that a handlebars template is rendered."""
- view = self.portal.restrictedTraverse('@@hbs_test_view')
- result_file = open(os.path.join(TEST_DATA__DIR, 'minimal.html'))
- self.assertEqual(view(), unicode(result_file.read(), encoding='utf-8'))
+ view = self.portal.restrictedTraverse("@@hbs_test_view")
+ result_file = open(os.path.join(TEST_DATA__DIR, "minimal.html"))
+ self.assertEqual(view(), six.ensure_text(result_file.read()))
def test_translate(self):
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
- component.provideUtility(TestDomain(Allowed=_('Erlaubt')),
- name='my.domain')
- self.assertEqual(view.translate(_('Allowed'), target_language='de'),
- (u'Erlaubt', 'de'))
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
+ component.provideUtility(
+ TestDomain(Allowed=_("Erlaubt")),
+ provides=ITranslationDomain,
+ name="my.domain",
+ )
+ self.assertEqual(
+ view.translate(_("Allowed"), target_language="de"),
+ (u"Erlaubt", "de"),
+ )
def test_translate_default_lang(self):
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
- component.provideUtility(TestDomain(Allowed=_('Allowed')),
- name='my.domain')
- self.assertEqual(view.translate(_('Allowed')), (u'Allowed', 'en'))
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
+ component.provideUtility(
+ TestDomain(Allowed=_("Allowed")),
+ provides=ITranslationDomain,
+ name="my.domain",
+ )
+ self.assertEqual(view.translate(_("Allowed")), (u"Allowed", "en"))
def test_hbs_snippet(self):
- view = DummyHbsFile(self.portal, self.layer['request'])
- result_file = open(os.path.join(TEST_DATA__DIR, 'minimal_file.html'))
- self.assertEqual(view(), unicode(result_file.read(), encoding='utf-8'))
+ view = DummyHbsFile(self.portal, self.layer["request"])
+ result_file = open(os.path.join(TEST_DATA__DIR, "minimal_file.html"))
+ self.assertEqual(view(), six.ensure_text(result_file.read()))
def test_hbs_snippet_nofile(self):
- view = DummyHbsFile(self.portal, self.layer['request'])
+ view = DummyHbsFile(self.portal, self.layer["request"])
self.assertRaises(ValueError, view.invalid)
def test_get_path_from_prefix(self):
- view = DummyHbsFile(self.portal, self.layer['request'])
- self.assertEqual(view.get_path_from_prefix(_prefix='.'), '.')
+ view = DummyHbsFile(self.portal, self.layer["request"])
+ self.assertEqual(view.get_path_from_prefix(_prefix="."), ".")
def test_helpers(self):
- view = HelperHbsView(self.portal, self.layer['request'])
- result_file = open(os.path.join(TEST_DATA__DIR, 'helper.html'))
- self.assertEqual(view(), unicode(result_file.read(), encoding='utf-8'))
+ view = HelperHbsView(self.portal, self.layer["request"])
+ result_file = open(os.path.join(TEST_DATA__DIR, "helper.html"))
+ self.assertEqual(view(), six.ensure_text(result_file.read()))
def test_render_helper(self):
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
- rendered = view._wrap_widget('Hello unittest')
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
+ rendered = view._wrap_widget("Hello unittest")
self.assertEqual(
- rendered, 'Hello unittest
')
+ rendered, "Hello unittest
"
+ )
class TestPloneView(unittest.TestCase):
@@ -151,55 +156,31 @@ class TestPloneView(unittest.TestCase):
def setUp(self):
"""Custom shared utility setup for tests."""
- self.portal = self.layer['portal']
- self.view = self.portal.restrictedTraverse('@@hbs_test_ploneview')
+ self.portal = self.layer["portal"]
+ self.view = self.portal.restrictedTraverse("@@hbs_test_ploneview")
def test_get_contents_default(self):
- """ Method `get_tile_data` is not implemented in base class
+ """Method `get_tile_data` is not implemented in base class
:return:
"""
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
self.assertRaises(NotImplementedError, view.get_contents)
def test_base_view(self):
- """ An error is raised, if no template is specified """
- view = HandlebarsBrowserView(self.portal, self.layer['request'])
+ """An error is raised, if no template is specified"""
+ view = HandlebarsBrowserView(self.portal, self.layer["request"])
self.assertRaises(ValueError, view)
def test_example_view(self):
"""Test that a handlebars template is rendered."""
- view = self.portal.restrictedTraverse('@@hbs_test_ploneview')
- if api.env.plone_version().startswith('5.0'):
- filename = os.path.join(TEST_DATA__DIR, 'minimal_plone.html')
+ view = self.portal.restrictedTraverse("@@hbs_test_ploneview")
+ if api.env.plone_version().startswith("5.0"):
+ filename = os.path.join(TEST_DATA__DIR, "minimal_plone.html")
else:
- filename = os.path.join(TEST_DATA__DIR, 'minimal_plone_51.html')
+ filename = os.path.join(TEST_DATA__DIR, "minimal_plone_51.html")
with open(filename) as f:
- self.assertIn(
- unicode(f.read().strip(), encoding='utf-8'),
- normalize(view())
- )
-
-
-class TestUninstall(unittest.TestCase):
-
- layer = COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING
-
- def setUp(self):
- self.portal = self.layer['portal']
- self.installer = api.portal.get_tool('portal_quickinstaller')
- self.installer.uninstallProducts(['collective.handlebars'])
-
- def test_product_uninstalled(self):
- """Test if collective.handlebars is cleanly uninstalled."""
- self.assertFalse(self.installer.isProductInstalled(
- 'collective.handlebars'))
-
- def test_browserlayer_removed(self):
- """Test that ICollectiveHandlebarsLayer is removed."""
- from collective.handlebars.interfaces import ICollectiveHandlebarsLayer
- from plone.browserlayer import utils
- self.assertNotIn(ICollectiveHandlebarsLayer, utils.registered_layers())
+ self.assertIn(six.ensure_text(f.read().strip()), normalize(view()))
class TestHandlebarTile(unittest.TestCase):
@@ -208,49 +189,53 @@ class TestHandlebarTile(unittest.TestCase):
layer = COLLECTIVE_HANDLEBARS_INTEGRATION_TESTING
def setUp(self):
- self.tile = HandlebarsTile(self.layer['portal'], self.layer['request'])
- self.template_path = os.path.join(TEST_DATA__DIR,
- '_slideshow_slide.js.hbs')
+ self.tile = HandlebarsTile(self.layer["portal"], self.layer["request"])
+ self.template_path = os.path.join(
+ TEST_DATA__DIR, "_slideshow_slide.js.hbs"
+ )
def test_get_contents_default(self):
- """ Method `get_tile_data` is not implemented in base class
+ """Method `get_tile_data` is not implemented in base class
:return:
"""
- view = HandlebarsBrowserView(self.layer['portal'],
- self.layer['request'])
+ view = HandlebarsBrowserView(
+ self.layer["portal"], self.layer["request"]
+ )
self.assertRaises(NotImplementedError, view.get_contents)
def test_get_hbs_template(self):
template = self.tile._get_hbs_template(self.template_path)
self.assertEqual(
- template({'src': 'foo', 'alt': 'bar'}).strip(),
- u''
+ template({"src": "foo", "alt": "bar"}).strip(),
+ u'',
)
def test_get_partial_key(self):
- self.assertEqual(self.tile._get_partial_key(self.template_path),
- '_slideshow_slide.js')
+ self.assertEqual(
+ self.tile._get_partial_key(self.template_path),
+ "_slideshow_slide.js",
+ )
def test_call_notemplate(self):
- """ An error is raised, if no template is specified """
+ """An error is raised, if no template is specified"""
self.assertRaises(ValueError, self.tile)
def test_call_with_template(self):
- tile = DummyHbsTile(self.layer['portal'], self.layer['request'])
- setattr(tile, 'index', DummyHbsTemplate(self.template_path))
+ tile = DummyHbsTile(self.layer["portal"], self.layer["request"])
+ setattr(tile, "index", DummyHbsTemplate(self.template_path))
self.assertEqual(
normalize(tile()),
- u''
+ u'',
)
def test_call_with_body_template(self):
- template_path = os.path.join(TEST_DATA__DIR, 'body_tile.hbs')
- tile = DummyHbsTile(self.layer['portal'], self.layer['request'])
- setattr(tile, 'index', DummyHbsTemplate(template_path))
+ template_path = os.path.join(TEST_DATA__DIR, "body_tile.hbs")
+ tile = DummyHbsTile(self.layer["portal"], self.layer["request"])
+ setattr(tile, "index", DummyHbsTemplate(template_path))
self.assertEqual(
tile().strip(),
- u''
+ u'',
)
@@ -261,38 +246,43 @@ class TestHandlebarPersistentTile(unittest.TestCase):
def setUp(self):
self.tile = HandlebarsPersistentTile(
- self.layer['portal'], self.layer['request'])
- self.template_path = os.path.join(TEST_DATA__DIR,
- '_slideshow_slide.js.hbs')
+ self.layer["portal"], self.layer["request"]
+ )
+ self.template_path = os.path.join(
+ TEST_DATA__DIR, "_slideshow_slide.js.hbs"
+ )
def test_get_contents_default(self):
- """ Method `get_tile_data` is not implemented in base class
+ """Method `get_tile_data` is not implemented in base class
:return:
"""
- view = HandlebarsBrowserView(self.layer['portal'],
- self.layer['request'])
+ view = HandlebarsBrowserView(
+ self.layer["portal"], self.layer["request"]
+ )
self.assertRaises(NotImplementedError, view.get_contents)
def test_get_hbs_template(self):
template = self.tile._get_hbs_template(self.template_path)
self.assertEqual(
- template({'src': 'foo', 'alt': 'bar'}).strip(),
- u''
+ template({"src": "foo", "alt": "bar"}).strip(),
+ u'',
)
def test_get_partial_key(self):
- self.assertEqual(self.tile._get_partial_key(self.template_path),
- '_slideshow_slide.js')
+ self.assertEqual(
+ self.tile._get_partial_key(self.template_path),
+ "_slideshow_slide.js",
+ )
def test_call_notemplate(self):
- """ An error is raised, if no template is specified """
+ """An error is raised, if no template is specified"""
self.assertRaises(ValueError, self.tile)
def test_call_with_template(self):
- tile = DummyHbsTile(self.layer['portal'], self.layer['request'])
- setattr(tile, 'index', DummyHbsTemplate(self.template_path))
+ tile = DummyHbsTile(self.layer["portal"], self.layer["request"])
+ setattr(tile, "index", DummyHbsTemplate(self.template_path))
self.assertEqual(
normalize(tile()),
- u''
+ u'',
)
diff --git a/versions.cfg b/versions.cfg
new file mode 100644
index 0000000..3412694
--- /dev/null
+++ b/versions.cfg
@@ -0,0 +1,24 @@
+[versions]
+# Don't use a released version of collective.handlebars
+collective.handlebars =
+zc.buildout =
+setuptools =
+zc.recipe.egg = 2.0.7
+PyMeta3 = 0.5.1
+PyYAML = 5.4.1
+chardet = 3.0.4
+check-manifest = 0.37
+configparser = 4.0.2
+coverage = 5.5
+flake8 = 3.9.2
+flake8-blind-except = 0.2.0
+flake8-coding = 1.3.2
+flake8-debugger = 3.2.1
+idna = 2.10
+mccabe = 0.6.1
+plone.recipe.codeanalysis = 3.0.1
+pybars3 = 0.9.7
+pycodestyle = 2.7.0
+pyflakes = 2.3.1
+python-coveralls = 2.9.3
+sh = 1.14.2