Skip to content

Commit

Permalink
Add tests + Py33 support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rémy HUBSCHER committed Oct 14, 2013
1 parent 343f9eb commit 3da237c
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 261 deletions.
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[run]
source = chartjs
omit = *settings.py*,*manage.py*
12 changes: 12 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
language: python
python:
- "2.7"
- "3.3"
install:
- python setup.py develop
- (cd demo; python setup.py develop)
script: flake8 chartjs && demo test demoproject
after_success:
# Report coverage results to coveralls.io
- pip install coveralls
- coveralls
2 changes: 1 addition & 1 deletion chartjs/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_context_data(self):
return data

def get_data(self):
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should return a data list list. '
'(i.e: [[25, 34, 0, 1, 50], ...]).')

Expand Down
10 changes: 5 additions & 5 deletions chartjs/views/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def get_title(self):
try:
return {'text': u'%s' % self.title}
except AttributeError:
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should define self.title or self.get_title')

def get_subtitle(self):
Expand All @@ -47,7 +47,7 @@ def get_xAxis(self):
return {'categories': self.get_labels()}

def get_labels(self):
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should return a labels list. '
'(i.e: ["January", ...])')

Expand All @@ -64,7 +64,7 @@ def get_yUnit(self):
try:
return self.yUnit
except AttributeError:
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'Please define the yAxis unit (self.yUnit).')

def get_tooltip(self):
Expand Down Expand Up @@ -109,7 +109,7 @@ def get_data(self):
In the same order as providers and with the same serie length
of xAxis.
"""
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should return a data list list. '
'(i.e: [[25, 34, 0, 1, 50], ...]).')

Expand All @@ -121,5 +121,5 @@ def get_providers(self):
try:
return self.providers
except AttributeError:
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should define self.providers of self.get_providers.')
7 changes: 5 additions & 2 deletions chartjs/views/lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ def get_datasets(self):
return datasets

def get_labels(self):
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should return a labels list. '
'(i.e: ["January", ...])')

def get_data(self):
raise NotImplementedError(
raise NotImplementedError( # pragma: no cover
'You should return a data list list. '
'(i.e: [[25, 34, 0, 1, 50], ...]).')

Expand All @@ -58,3 +58,6 @@ def get_context_data(self):
data['series'] = self.get_series()
data['yAxis'] = {'title': {'text': u'%s' % self.y_axis_title}}
return data

def get_providers(self):
return []
11 changes: 11 additions & 0 deletions demo/demoproject/_compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
import sys

PY2 = sys.version_info[0] == 2


def decode(string):
"""Wrapper around 'print' for Py2/3 _compatibility."""
if not PY2:
return string.decode('utf-8')
return string
6 changes: 3 additions & 3 deletions demo/demoproject/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@
'--nocapture',
'--rednose',
'--with-id', # allows --failed which only reruns failed tests
'--id-file=%s' % join(data_dir, 'test', 'noseids'),
'--id-file=%s' % join(data_dir, 'noseids'),
'--with-doctest',
'--with-xunit',
'--xunit-file=%s' % join(data_dir, 'test', 'nosetests.xml'),
'--xunit-file=%s' % join(data_dir, 'nosetests.xml'),
'--with-coverage',
'--cover-erase',
'--cover-package=demoproject,i18nurl',
'--cover-package=chartjs',
'--no-path-adjustment',
'--all-modules',
]
240 changes: 42 additions & 198 deletions demo/demoproject/tests.py
Original file line number Diff line number Diff line change
@@ -1,211 +1,55 @@
"""Unit tests for language automatic and manual selection."""
from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils import translation
from django.utils.importlib import import_module
from django.test import TestCase

from i18nurl.settings import I18N_REDIRECT_URL_NAME, I18N_LANGUAGES


class I18nTestCase(TestCase):
"""Base class for posbox.i18n tests classes."""
def setUp(self):
"""Common setup for all test methods:
* Assigns self.guess_language_url and self.set_language_url.
"""
super(I18nTestCase, self).setUp()
self.guess_language_url = reverse('guess_language')
self.set_language_url = reverse('set_language')
self.default_language = settings.LANGUAGE_CODE
for language_code, language_name in settings.LANGUAGES:
if language_code != settings.LANGUAGE_CODE:
self.other_language = language_code
break
with translation.override(self.default_language):
url_name = I18N_REDIRECT_URL_NAME
self.default_redirect_url = reverse(url_name)
with translation.override(self.other_language):
self.other_redirect_url = reverse(I18N_REDIRECT_URL_NAME)

def set_language(self, language_code, redirect_url=None, temporary=False,
**kwargs):
"""Perform a set_language request with self.client and return
response."""
data = {'language': language_code}
if redirect_url:
data['next'] = redirect_url
if temporary:
data['temporary'] = 1
return self.client.post(self.set_language_url, data, **kwargs)

def set_session_language(self, language):
"""Set session's django_language to language. Creates a new session
instance if necessary."""
if settings.SESSION_COOKIE_NAME in self.client.cookies:
session = self.client.session
else: # Create a new session.
engine = import_module(settings.SESSION_ENGINE)
session = engine.SessionStore()
session.create()
key = session._session_key
self.client.cookies[settings.SESSION_COOKIE_NAME] = key
session['django_language'] = language
session.save()

def assertI18nRedirection(self, response, redirect_url=None, msg=None):
"""Assert response is a redirection to redirect_url.
.. note:: response must have been fetched with ``follow=True``.
If ``redirect_url`` is None, it defaults to self.default_redirect_url.
"""
# We don't use self.assertRedirects() because it checks the status code
# of the response at the end of the redirection chain. The status code
# at the end of the redirection chain is supposed to be tested as of
# another's view test suite, i.e. it's not in the scope of current
# method. In fact, right here, we don't know the status code to expect!
# As an example, the first redirection could lead to the homepage,
# which could be HTTP 200 or HTTP 301 depending on the implementation.
if redirect_url is None:
redirect_url = self.default_redirect_url
redirection = ('http://testserver%s' % redirect_url, 302)
args = []
if msg is not None:
args.append(msg)
self.assertEqual(response.redirect_chain[0], redirection, *args)
"""Unit tests for chartjs api."""
import json

from django.test import TestCase
from django.core.urlresolvers import reverse

class GuessLanguageTestCase(I18nTestCase):
"""Test automatic language detection."""
def test_no_guess(self):
"""Without data to guess (user preferences, session, cookies or
HTTP_ACCEPT_LANGUAGE header), the guess_language view redirects to
to the default language website, with a message."""
response = self.client.get(self.guess_language_url, follow=True)
self.assertI18nRedirection(response)
from demoproject._compat import decode

def test_guess_http_accept_language(self):
"""With HTTP_ACCEPT_LANGUAGE header only, the guess_language view
redirects to the right website."""
response = self.client.get(self.guess_language_url,
HTTP_ACCEPT_LANGUAGE=self.other_language,
follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)

def test_guess_cookie(self):
"""With a language cookie only, then the guess_language view redirects
to the right website."""
self.client.cookies[settings.LANGUAGE_COOKIE_NAME] = self.other_language
response = self.client.get(self.guess_language_url, follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)
class LineChartJSTestCase(TestCase):
def test_line_chartjs(self):
resp = self.client.get(reverse('line_chart'))
self.assertContains(resp, 'Chart.min.js')

def test_guess_session(self):
"""With a language set in session only, then the guess_language view
redirects to the right website."""
self.set_session_language(self.other_language)
response = self.client.get(self.guess_language_url, follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)
def test_list_chartjs_json(self):
resp = self.client.get(reverse('line_chart_json'))
try:
data = json.loads(decode(resp.content))
except ValueError:
self.fail("%r is not valid json" % self.resp.content)

def test_detection_order(self):
"""Language detection is performed in the order specified in
settings."""
# Alternatives are sorted by priority. "user_profile" has precedence
# over "session", which has precedence over "cookie", ...
alternatives = ['session', 'cookie',
'http_accept_language', 'default']
# For each pair of alternatives, we setup the client to request
# the "other" language using the "major" alternative, and, at the
# same time, request the "default" language using the "minor"
# alternative.
for i in range(0, len(alternatives)):
# Reset request parameters.
request_kwargs = {}
self.client.cookies.clear()
redirect_url = self.other_redirect_url
major = alternatives[i]
try:
minor = alternatives[i + 1]
except IndexError:
break
# Setup request with major alternative.
if major == 'session':
self.set_session_language(self.other_language)
elif major == 'cookie':
self.client.cookies[settings.LANGUAGE_COOKIE_NAME] = self.other_language
elif major == 'http_accept_language':
request_kwargs['HTTP_ACCEPT_LANGUAGE'] = self.other_language
elif major == 'default':
# In that particular case, we expect that we are redirected to
# the default website.
redirect_url = self.default_redirect_url
# Setup request with minor alternative.
if minor == 'session':
self.set_session_language(self.default_language)
elif minor == 'cookie':
self.client.cookies[settings.LANGUAGE_COOKIE_NAME] = self.default_language
elif minor == 'http_accept_language':
request_kwargs['HTTP_ACCEPT_LANGUAGE'] = self.default_language
elif minor == 'default':
pass
response = self.client.get(self.guess_language_url,
follow=True,
**request_kwargs)
error_msg = 'Language detection failed: "%(major)s" detection ' \
'does not have precedence over "%(minor)s"' \
% {'major': major, 'minor': minor}
self.assertI18nRedirection(response, redirect_url, error_msg)
self.assertIn('datasets', data)
self.assertNotIn('series', data)


class SetLanguageTestCase(I18nTestCase):
"""Test language change actions."""
def test_language_list(self):
"""Called without arguments and without POST, set_language view
displays a list of available languages."""
response = self.client.get(self.set_language_url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'i18n/set_language.html')
class ColorTestCase(TestCase):
def test_colorview(self):
resp = self.client.get(reverse('colors'))
self.assertContains(resp, '100px')

def test_redirection(self):
"""Called with language argument, set_language view redirects to the
website with specified language activated."""
data = {'language': self.other_language}
response = self.client.post(self.set_language_url, data, follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)

def test_language_setting(self):
"""After a "set_language", "guess_language" detects the language that
was just set."""
# Call "set_language" with a language which is not the default.
response = self.set_language(self.other_language, follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)
# Then call "guess_language": the previously set language should be
# detected.
response = self.client.get(self.guess_language_url, follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)
class HighChartJSTestCase(TestCase):
def test_list_chartjs_json(self):
resp = self.client.get(reverse('line_highchart_json'))
try:
data = json.loads(decode(resp.content))
except ValueError:
self.fail("%r is not valid json" % self.resp.content)

def test_temporary_redirection(self):
"""Called with "temporary" argument to True, set_language view doesn't
remember the selected language in user profile, session, cookies..."""
# Call "set_language" with a language which is not the default.
response = self.set_language(self.other_language, temporary=True,
follow=True)
self.assertI18nRedirection(response, self.other_redirect_url)
# Then call "guess_language": the default language should be detected.
response = self.client.get(self.guess_language_url, follow=True)
self.assertI18nRedirection(response, self.default_redirect_url)
self.assertIn('series', data)
self.assertNotIn('datasets', data)

def test_pie_chartjs_json(self):
resp = self.client.get(reverse('pie_highchart_json'))
try:
json.loads(decode(resp.content))
except ValueError:
self.fail("%r is not valid json" % self.resp.content)

class I18nURLTestCase(I18nTestCase):
"""Test localized URL patterns."""
def test_i18n_url(self):
"""set_language and guess_language URL aren't localized."""
for view_name in 'set_language', 'guess_language':
with translation.override(self.default_language):
default_url = reverse(view_name)
with translation.override(self.other_language):
other_url = reverse(view_name)
self.assertEqual(default_url, other_url)
def test_donut_chartjs_json(self):
resp = self.client.get(reverse('donut_highchart_json'))
try:
json.loads(decode(resp.content))
except ValueError:
self.fail("%r is not valid json" % self.resp.content)
6 changes: 6 additions & 0 deletions demo/demoproject/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,10 @@
url(r'^colors/$', views.colors, name='colors'),
url(r'^line_chart/$', views.line_chart, name='line_chart'),
url(r'^line_chart/json/$', views.line_chart_json, name='line_chart_json'),
url(r'^line_highchart/json/$', views.line_highchart_json,
name='line_highchart_json'),
url(r'^pie_highchart/json/$', views.pie_highchart_json,
name='pie_highchart_json'),
url(r'^donut_highchart/json/$', views.donut_highchart_json,
name='donut_highchart_json'),
)
Loading

0 comments on commit 3da237c

Please sign in to comment.