Commit 4aa4c514 by Ned Batchelder

Add i18n attribute to LoncapaSystem

[LMS-1597]
parent d2146978
...@@ -71,7 +71,11 @@ class LoncapaSystem(object): ...@@ -71,7 +71,11 @@ class LoncapaSystem(object):
can provide these resources however make sense for their environment, and can provide these resources however make sense for their environment, and
this code can remain independent. this code can remain independent.
See :class:`ModuleSystem` for documentation of these attributes. Attributes:
i18n: an object implementing the `gettext.Translations` interface so
that we can use `.ugettext` to localize strings.
See :class:`ModuleSystem` for documentation of other attributes.
""" """
def __init__( # pylint: disable=invalid-name def __init__( # pylint: disable=invalid-name
...@@ -82,6 +86,7 @@ class LoncapaSystem(object): ...@@ -82,6 +86,7 @@ class LoncapaSystem(object):
can_execute_unsafe_code, can_execute_unsafe_code,
DEBUG, # pylint: disable=invalid-name DEBUG, # pylint: disable=invalid-name
filestore, filestore,
i18n,
node_path, node_path,
render_template, render_template,
seed, # Why do we do this if we have self.seed? seed, # Why do we do this if we have self.seed?
...@@ -94,6 +99,7 @@ class LoncapaSystem(object): ...@@ -94,6 +99,7 @@ class LoncapaSystem(object):
self.can_execute_unsafe_code = can_execute_unsafe_code self.can_execute_unsafe_code = can_execute_unsafe_code
self.DEBUG = DEBUG # pylint: disable=invalid-name self.DEBUG = DEBUG # pylint: disable=invalid-name
self.filestore = filestore self.filestore = filestore
self.i18n = i18n
self.node_path = node_path self.node_path = node_path
self.render_template = render_template self.render_template = render_template
self.seed = seed # Why do we do this if we have self.seed? self.seed = seed # Why do we do this if we have self.seed?
......
...@@ -875,8 +875,9 @@ class NumericalResponse(LoncapaResponse): ...@@ -875,8 +875,9 @@ class NumericalResponse(LoncapaResponse):
correct_ans = evaluator({}, {}, self.correct_answer) correct_ans = evaluator({}, {}, self.correct_answer)
except Exception: except Exception:
log.debug("Content error--answer '%s' is not a valid number", self.correct_answer) log.debug("Content error--answer '%s' is not a valid number", self.correct_answer)
_ = self.capa_system.i18n.ugettext
raise StudentInputError( raise StudentInputError(
"There was a problem with the staff answer to this problem" _("There was a problem with the staff answer to this problem")
) )
return correct_ans return correct_ans
......
"""Tools for helping with testing capa.""" """Tools for helping with testing capa."""
import gettext
import os import os
import os.path import os.path
...@@ -41,6 +42,7 @@ def test_capa_system(): ...@@ -41,6 +42,7 @@ def test_capa_system():
can_execute_unsafe_code=lambda: False, can_execute_unsafe_code=lambda: False,
DEBUG=True, DEBUG=True,
filestore=fs.osfs.OSFS(os.path.join(TEST_DIR, "test_files")), filestore=fs.osfs.OSFS(os.path.join(TEST_DIR, "test_files")),
i18n=gettext.NullTranslations(),
node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"), node_path=os.environ.get("NODE_PATH", "/usr/local/lib/node_modules"),
render_template=tst_render_template, render_template=tst_render_template,
seed=0, seed=0,
......
...@@ -1140,6 +1140,24 @@ class NumericalResponseTest(ResponseTest): ...@@ -1140,6 +1140,24 @@ class NumericalResponseTest(ResponseTest):
"Content error--answer '%s' is not a valid number", staff_ans "Content error--answer '%s' is not a valid number", staff_ans
) )
@mock.patch('capa.responsetypes.log')
def test_responsetype_i18n(self, mock_log):
"""Test that LoncapaSystem has an i18n that works."""
staff_ans = "clearly bad syntax )[+1e"
problem = self.build_problem(answer=staff_ans, tolerance=1e-3)
class FakeTranslations(object):
"""A fake gettext.Translations object."""
def ugettext(self, text):
"""Return the 'translation' of `text`."""
if text == "There was a problem with the staff answer to this problem":
text = "TRANSLATED!"
return text
problem.capa_system.i18n = FakeTranslations()
with self.assertRaisesRegexp(StudentInputError, "TRANSLATED!"):
self.assert_grade(problem, '1+j', 'correct')
def test_grade_infinity(self): def test_grade_infinity(self):
""" """
Check that infinity doesn't automatically get marked correct. Check that infinity doesn't automatically get marked correct.
......
...@@ -267,6 +267,7 @@ class CapaMixin(CapaFields): ...@@ -267,6 +267,7 @@ class CapaMixin(CapaFields):
can_execute_unsafe_code=self.system.can_execute_unsafe_code, can_execute_unsafe_code=self.system.can_execute_unsafe_code,
DEBUG=self.system.DEBUG, DEBUG=self.system.DEBUG,
filestore=self.system.filestore, filestore=self.system.filestore,
i18n=self.system.service(self, "i18n"),
node_path=self.system.node_path, node_path=self.system.node_path,
render_template=self.system.render_template, render_template=self.system.render_template,
seed=self.system.seed, # Why do we do this if we have self.seed? seed=self.system.seed, # Why do we do this if we have self.seed?
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment