Progress tracking cleanup.

* use clearer names for the two status strings passed to js
* add functions to do canonical conversion of progress to js string
* fix updating bug in sequence.coffee
* add some todo comments and other docs to make future expansion easier
This commit is contained in:
Victor Shnayder
2012-06-20 16:01:56 -04:00
committed by Matthew Mongeau
parent 17f8d04c28
commit 3961a5d8ca
7 changed files with 71 additions and 10 deletions

View File

@@ -298,7 +298,7 @@ class Module(XModule):
after = self.get_progress()
d.update({
'progress_changed' : after != before,
'progress' : after.ternary_str(),
'progress_status' : Progress.to_js_status_str(after),
})
return json.dumps(d, cls=ComplexEncoder)

View File

@@ -1,6 +1,17 @@
'''
Progress class for modules. Represents where a student is in a module.
'''
Useful things to know:
- Use Progress.to_js_status_str() to convert a progress into a simple
status string to pass to js.
- Use Progress.to_js_detail_str() to convert a progress into a more detailed
string to pass to js.
In particular, these functions have a canonical handing of None.
For most subclassing needs, you should only need to reimplement
frac() and __str__().
'''
from collections import namedtuple
import numbers
@@ -124,3 +135,26 @@ class Progress(object):
(n, d) = a.frac()
(n2, d2) = b.frac()
return Progress(n + n2, d + d2)
@staticmethod
def to_js_status_str(progress):
'''
Return the "status string" version of the passed Progress
object that should be passed to js. Use this function when
sending Progress objects to js to limit dependencies.
'''
if progress is None:
return "NA"
return progress.ternary_str()
@staticmethod
def to_js_detail_str(progress):
'''
Return the "detail string" version of the passed Progress
object that should be passed to js. Use this function when
passing Progress objects to js to limit dependencies.
'''
if progress is None:
return "NA"
return str(progress)

View File

@@ -74,8 +74,8 @@ class Module(XModule):
for contents, title, progress in zip(self.contents, titles, progresses):
contents['title'] = title
contents['progress_str'] = str(progress) if progress is not None else ""
contents['progress_stat'] = progress.ternary_str() if progress is not None else ""
contents['progress_status'] = Progress.to_js_status_str(progress)
contents['progress_detail'] = Progress.to_js_detail_str(progress)
for (content, element_class) in zip(self.contents, child_classes):
new_class = 'other'

View File

@@ -568,6 +568,22 @@ class ProgressTest(unittest.TestCase):
self.assertEqual(self.half_done.ternary_str(), "in_progress")
self.assertEqual(self.done.ternary_str(), "done")
def test_to_js_status(self):
'''Test the Progress.to_js_status_str() method'''
self.assertEqual(Progress.to_js_status_str(self.not_started), "none")
self.assertEqual(Progress.to_js_status_str(self.half_done), "in_progress")
self.assertEqual(Progress.to_js_status_str(self.done), "done")
self.assertEqual(Progress.to_js_status_str(None), "NA")
def test_to_js_detail_str(self):
'''Test the Progress.to_js_detail_str() method'''
f = Progress.to_js_detail_str
for p in (self.not_started, self.half_done, self.done):
self.assertEqual(f(p), str(p))
# But None should be encoded as NA
self.assertEqual(f(None), "NA")
def test_add(self):
'''Test the Progress.add_counts() method'''
p = Progress(0, 2)