def test_str(self): assert str(self.not_started) == '0/17' assert str(self.part_done) == '2/6' assert str(self.done) == '7/7' assert str(Progress(2.1234, 7)) == '2.12/7' assert str(Progress(2.0034, 7)) == '2/7' assert str(Progress(0.999, 7)) == '1/7'
def test_str(self): self.assertEqual(str(self.not_started), "0/17") self.assertEqual(str(self.part_done), "2/6") self.assertEqual(str(self.done), "7/7") self.assertEqual(str(Progress(2.1234, 7)), '2.12/7') self.assertEqual(str(Progress(2.0034, 7)), '2/7') self.assertEqual(str(Progress(0.999, 7)), '1/7')
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), "0")
def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' prg1 = Progress(1, 2) prg2 = Progress(2, 4) prg3 = Progress(1, 2) self.assertEqual(prg1, prg3) self.assertNotEqual(prg1, prg2) # Check != while we're at it self.assertNotEqual(prg1, prg2) self.assertEqual(prg1, prg3)
def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' p = Progress(1, 2) p2 = Progress(2, 4) p3 = Progress(1, 2) self.assertTrue(p == p3) self.assertFalse(p == p2) # Check != while we're at it self.assertTrue(p != p2) self.assertFalse(p != p3)
def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' prg1 = Progress(1, 2) prg2 = Progress(2, 4) prg3 = Progress(1, 2) assert prg1 == prg3 assert prg1 != prg2 # Check != while we're at it assert prg1 != prg2 assert prg1 == prg3
def test_add(self): '''Test the Progress.add_counts() method''' p = Progress(0, 2) p2 = Progress(1, 3) p3 = Progress(2, 5) pNone = None add = lambda a, b: Progress.add_counts(a, b).frac() self.assertEqual(add(p, p), (0, 4)) self.assertEqual(add(p, p2), (1, 5)) self.assertEqual(add(p2, p3), (3, 8)) self.assertEqual(add(p2, pNone), p2.frac()) self.assertEqual(add(pNone, p2), p2.frac())
def test_add(self): '''Test the Progress.add_counts() method''' prg1 = Progress(0, 2) prg2 = Progress(1, 3) prg3 = Progress(2, 5) prg_none = None add = lambda a, b: Progress.add_counts(a, b).frac() self.assertEqual(add(prg1, prg1), (0, 4)) self.assertEqual(add(prg1, prg2), (1, 5)) self.assertEqual(add(prg2, prg3), (3, 8)) self.assertEqual(add(prg2, prg_none), prg2.frac()) self.assertEqual(add(prg_none, prg2), prg2.frac())
def student_view(self, context): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() for child in self.get_display_items(): progress = child.get_progress() rendered_child = child.render('student_view', context) fragment.add_frag_resources(rendered_child) childinfo = { 'content': rendered_child.content, 'title': "\n".join(grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None), 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.id, } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default contents.append(childinfo) params = { 'items': contents, 'element_id': self.location.html_id(), 'item_id': self.id, 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, } fragment.add_content( self.system.render_template('seq_module.html', params)) return fragment
def handle_ajax(self, dispatch, data, system): """ This is called by courseware.module_render, to handle an AJAX call. "data" is request.POST. Returns a json dictionary: { 'progress_changed' : True/False, 'progress' : 'none'/'in_progress'/'done', <other request-specific values here > } """ handlers = { "save_answer": self.save_answer, "score_update": self.update_score, "save_post_assessment": self.message_post, "skip_post_assessment": self.skip_post_assessment, "check_for_score": self.check_for_score, } if dispatch not in handlers: # This is a dev_facing_error log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch)) # This is a dev_facing_error return json.dumps({"error": "Error handling action. Please try again.", "success": False}) before = self.get_progress() d = handlers[dispatch](data, system) after = self.get_progress() d.update({"progress_changed": after != before, "progress_status": Progress.to_js_status_str(after)}) return json.dumps(d, cls=ComplexEncoder)
def handle_ajax(self, dispatch, data, system): ''' This is called by courseware.module_render, to handle an AJAX call. "data" is request.POST. Returns a json dictionary: { 'progress_changed' : True/False, 'progress' : 'none'/'in_progress'/'done', <other request-specific values here > } ''' handlers = { 'save_answer': self.save_answer, 'score_update': self.update_score, 'save_post_assessment': self.message_post, 'skip_post_assessment': self.skip_post_assessment, 'check_for_score': self.check_for_score, } if dispatch not in handlers: # This is a dev_facing_error log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch)) # This is a dev_facing_error return json.dumps({'error': 'Error handling action. Please try again.', 'success': False}) before = self.get_progress() d = handlers[dispatch](data, system) after = self.get_progress() d.update({ 'progress_changed': after != before, 'progress_status': Progress.to_js_status_str(after), }) return json.dumps(d, cls=ComplexEncoder)
def handle_ajax(self, dispatch, data, system): ''' This is called by courseware.module_render, to handle an AJAX call. "data" is request.POST. Returns a json dictionary: { 'progress_changed' : True/False, 'progress' : 'none'/'in_progress'/'done', <other request-specific values here > } ''' handlers = { 'save_answer': self.save_answer, 'score_update': self.update_score, 'save_post_assessment': self.message_post, 'skip_post_assessment': self.skip_post_assessment, 'check_for_score': self.check_for_score, 'store_answer': self.store_answer, } _ = self.system.service(self, "i18n").ugettext if dispatch not in handlers: # This is a dev_facing_error log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch)) # This is a dev_facing_error return json.dumps( {'error': _('Error handling action. Please try again.'), 'success': False} ) before = self.get_progress() d = handlers[dispatch](data, system) after = self.get_progress() d.update({ 'progress_changed': after != before, 'progress_status': Progress.to_js_status_str(after), }) return json.dumps(d, cls=ComplexEncoder)
def handle_ajax(self, dispatch, data, system): """ This is called by courseware.module_render, to handle an AJAX call. "data" is request.POST. Returns a json dictionary: { 'progress_changed' : True/False, 'progress': 'none'/'in_progress'/'done', <other request-specific values here > } """ handlers = { 'save_answer': self.save_answer, 'save_text': self.save_text, 'save_assessment': self.save_assessment, 'save_post_assessment': self.save_hint, 'remove_file': self.remove_file } if dispatch not in handlers: # This is a dev_facing_error log.error("Cannot find {0} in handlers in handle_ajax function for open_ended_module.py".format(dispatch)) # This is a dev_facing_error return json.dumps({'error': 'Error handling action. Please try again.', 'success': False}) before = self.get_progress() d = handlers[dispatch](data, system) after = self.get_progress() d.update({ 'progress_changed': after != before, 'progress_status': Progress.to_js_status_str(after), }) return json.dumps(d, cls=ComplexEncoder)
def test_create_object(self): # These should work: p = Progress(0, 2) p = Progress(1, 2) p = Progress(2, 2) p = Progress(2.5, 5.0) p = Progress(3.7, 12.3333) # These shouldn't self.assertRaises(ValueError, Progress, 0, 0) self.assertRaises(ValueError, Progress, 2, 0) self.assertRaises(ValueError, Progress, 1, -2) self.assertRaises(TypeError, Progress, 0, "all") # check complex numbers just for the heck of it :) self.assertRaises(TypeError, Progress, 2j, 3)
def test_create_object(self): # These should work: prg1 = Progress(0, 2) # pylint: disable=unused-variable prg2 = Progress(1, 2) # pylint: disable=unused-variable prg3 = Progress(2, 2) # pylint: disable=unused-variable prg4 = Progress(2.5, 5.0) # pylint: disable=unused-variable prg5 = Progress(3.7, 12.3333) # pylint: disable=unused-variable # These shouldn't self.assertRaises(ValueError, Progress, 0, 0) self.assertRaises(ValueError, Progress, 2, 0) self.assertRaises(ValueError, Progress, 1, -2) self.assertRaises(TypeError, Progress, 0, "all") # check complex numbers just for the heck of it :) self.assertRaises(TypeError, Progress, 2j, 3)
def student_view(self, context): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() for child in self.get_display_items(): progress = child.get_progress() rendered_child = child.render("student_view", context) fragment.add_frag_resources(rendered_child) childinfo = { "content": rendered_child.content, "title": "\n".join( grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None ), "progress_status": Progress.to_js_status_str(progress), "progress_detail": Progress.to_js_detail_str(progress), "type": child.get_icon_class(), "id": child.id, } if childinfo["title"] == "": childinfo["title"] = child.display_name_with_default contents.append(childinfo) params = { "items": contents, "element_id": self.location.html_id(), "item_id": self.id, "position": self.position, "tag": self.location.category, "ajax_url": self.system.ajax_url, } fragment.add_content(self.system.render_template("seq_module.html", params)) return fragment
def student_view(self, context): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 ## Returns a set of all types of all sub-children contents = [] fragment = Fragment() for child in self.get_display_items(): progress = child.get_progress() rendered_child = child.render('student_view', context) fragment.add_frag_resources(rendered_child) childinfo = { 'content': rendered_child.content, 'title': "\n".join( grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None ), 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.id, } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default contents.append(childinfo) params = {'items': contents, 'element_id': self.location.html_id(), 'item_id': self.id, 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, } fragment.add_content(self.system.render_template('seq_module.html', params)) return fragment
def render(self): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 if self.rendered: return ## Returns a set of all types of all sub-children contents = [] for child in self.get_display_items(): progress = child.get_progress() childinfo = { 'content': self.runtime.render_child(child, None, 'student_view').content, 'title': "\n".join(grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None), 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.id, } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default contents.append(childinfo) params = { 'items': contents, 'element_id': self.location.html_id(), 'item_id': self.id, 'position': self.position, 'tag': self.location.category } self.content = self.system.render_template('seq_module.html', params) self.rendered = True
def get_progress(self): ''' Return a progress.Progress object that represents how far the student has gone in this module. Must be implemented to get correct progress tracking behavior in nesting modules like sequence and vertical. If this module has no notion of progress, return None. ''' progress_object = Progress(self.current_task_number, len(self.task_xml)) return progress_object
def get_html(self): if self.contents is None: self.contents = [{ 'id': child.id, 'content': child.get_html(), 'direct_term': self.direct_term, 'progress_detail': Progress.to_js_detail_str(self.get_progress()) } for child in self.get_display_items()] return self.system.render_template('vert_module.html', { 'items': self.contents })
def get_progress(self): ''' For now, just return last score / max_score ''' if self._max_score > 0: try: return Progress(int(self.get_score()['score']), int(self._max_score)) except Exception as err: # This is a dev_facing_error log.exception("Got bad progress from open ended child module. Max Score: {0}".format(self._max_score)) return None return None
def render(self): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 if self.rendered: return ## Returns a set of all types of all sub-children contents = [] for child in self.get_display_items(): progress = child.get_progress() childinfo = { 'content': child.get_html(), 'title': "\n".join( grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None ), 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), 'id': child.id, 'direct_term': child.direct_term_with_default } if childinfo['title'] == '': childinfo['title'] = child.display_name_with_default contents.append(childinfo) params = {'items': contents, 'element_id': self.location.html_id(), 'item_id': self.id, 'position': self.position, 'tag': self.location.category } self.content = self.system.render_template('seq_module.html', params) self.rendered = True
def render(self): # If we're rendering this sequence, but no position is set yet, # default the position to the first element if self.position is None: self.position = 1 if self.rendered: return ## Returns a set of all types of all sub-children contents = [] for child in self.get_display_items(): progress = child.get_progress() childinfo = { "content": child.get_html(), "title": "\n".join( grand_child.display_name for grand_child in child.get_children() if grand_child.display_name is not None ), "progress_status": Progress.to_js_status_str(progress), "progress_detail": Progress.to_js_detail_str(progress), "type": child.get_icon_class(), "id": child.id, } if childinfo["title"] == "": childinfo["title"] = child.display_name_with_default contents.append(childinfo) params = { "items": contents, "element_id": self.location.html_id(), "item_id": self.id, "position": self.position, "tag": self.location.category, } self.content = self.system.render_template("seq_module.html", params) self.rendered = True
def test_add(self): '''Test the Progress.add_counts() method''' prg1 = Progress(0, 2) prg2 = Progress(1, 3) prg3 = Progress(2, 5) prg_none = None add = lambda a, b: Progress.add_counts(a, b).frac() assert add(prg1, prg1) == (0, 4) assert add(prg1, prg2) == (1, 5) assert add(prg2, prg3) == (3, 8) assert add(prg2, prg_none) == prg2.frac() assert add(prg_none, prg2) == prg2.frac()
def get_progress(self): """ Generate a progress object. Progress objects represent how far the student has gone in this module. Must be implemented to get correct progress tracking behavior in nested modules like sequence and vertical. This behavior is consistent with capa. If the module is unscored, return None (consistent with capa). """ d = self.get_score() if d['total'] > 0 and self.is_scored: try: return Progress(d['score'], d['total']) except (TypeError, ValueError): log.exception("Got bad progress") return None return None
def student_view(self, context): fragment = Fragment() contents = [] all_contents = [] for child in self.get_display_items(): rendered_child = child.render('student_view', context) fragment.add_frag_resources(rendered_child) show_now = 'true' try: problem_now = child.problem_now if not problem_now: show_now = 'false' except AttributeError: pass all_contents.append({ 'id': child.id, 'content': rendered_child.content, 'father': self.id, 'direct_term': self.direct_term, 'progress_detail': Progress.to_js_detail_str(self.get_progress()), 'type': child.get_icon_class(), 'show_now': show_now, 'problem_time': child.problem_time if child.get_icon_class() == 'problem' else [{"id": child2.id if child2.get_icon_class() == 'problem' else "video", "time": child2.problem_time if child2.get_icon_class() == 'problem' and child2.problem_time is not None else "video", } for child2 in self.get_display_items()] }) if self.random_problem_count == -1: contents = all_contents else: contents = random.sample(all_contents, self.random_problem_count) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents })) return fragment
def test_frac(self): prg = Progress(1, 2) (a_mem, b_mem) = prg.frac() self.assertEqual(a_mem, 1) self.assertEqual(b_mem, 2)
def test_frac(self): p = Progress(1, 2) (a, b) = p.frac() self.assertEqual(a, 1) self.assertEqual(b, 2)
def test_clamp(self): assert (2, 2) == Progress(3, 2).frac() assert (0, 2) == Progress((-2), 2).frac()
def test_frac(self): prg = Progress(1, 2) (a_mem, b_mem) = prg.frac() assert a_mem == 1 assert b_mem == 2
class ProgressTest(unittest.TestCase): ''' Test that basic Progress objects work. A Progress represents a fraction between 0 and 1. ''' not_started = Progress(0, 17) part_done = Progress(2, 6) half_done = Progress(3, 6) also_half_done = Progress(1, 2) done = Progress(7, 7) def test_create_object(self): # These should work: prg1 = Progress(0, 2) # pylint: disable=unused-variable prg2 = Progress(1, 2) # pylint: disable=unused-variable prg3 = Progress(2, 2) # pylint: disable=unused-variable prg4 = Progress(2.5, 5.0) # pylint: disable=unused-variable prg5 = Progress(3.7, 12.3333) # pylint: disable=unused-variable # These shouldn't self.assertRaises(ValueError, Progress, 0, 0) self.assertRaises(ValueError, Progress, 2, 0) self.assertRaises(ValueError, Progress, 1, -2) self.assertRaises(TypeError, Progress, 0, "all") # check complex numbers just for the heck of it :) self.assertRaises(TypeError, Progress, 2j, 3) def test_clamp(self): assert (2, 2) == Progress(3, 2).frac() assert (0, 2) == Progress((-2), 2).frac() def test_frac(self): prg = Progress(1, 2) (a_mem, b_mem) = prg.frac() assert a_mem == 1 assert b_mem == 2 def test_percent(self): assert self.not_started.percent() == 0 assert round(self.part_done.percent() - 33.33333333333333, 7) >= 0 assert self.half_done.percent() == 50 assert self.done.percent() == 100 assert self.half_done.percent() == self.also_half_done.percent() def test_started(self): assert not self.not_started.started() assert self.part_done.started() assert self.half_done.started() assert self.done.started() def test_inprogress(self): # only true if working on it assert not self.done.inprogress() assert not self.not_started.inprogress() assert self.part_done.inprogress() assert self.half_done.inprogress() def test_done(self): assert self.done.done() assert not self.half_done.done() assert not self.not_started.done() def test_str(self): assert str(self.not_started) == '0/17' assert str(self.part_done) == '2/6' assert str(self.done) == '7/7' assert str(Progress(2.1234, 7)) == '2.12/7' assert str(Progress(2.0034, 7)) == '2/7' assert str(Progress(0.999, 7)) == '1/7' def test_add(self): '''Test the Progress.add_counts() method''' prg1 = Progress(0, 2) prg2 = Progress(1, 3) prg3 = Progress(2, 5) prg_none = None add = lambda a, b: Progress.add_counts(a, b).frac() assert add(prg1, prg1) == (0, 4) assert add(prg1, prg2) == (1, 5) assert add(prg2, prg3) == (3, 8) assert add(prg2, prg_none) == prg2.frac() assert add(prg_none, prg2) == prg2.frac() def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' prg1 = Progress(1, 2) prg2 = Progress(2, 4) prg3 = Progress(1, 2) assert prg1 == prg3 assert prg1 != prg2 # Check != while we're at it assert prg1 != prg2 assert prg1 == prg3
def elementary_conjunction(term, section): error_return = True if len(term["source_element_id"]) == 0: return error_return if len(term["field"]) == 0: return error_return if len(term["sign"]) == 0: return error_return if len(term["value"]) == 0: return error_return unit = get_unit(term["source_element_id"], section) if not unit: return error_return value = 0 term["value"] = int(term["value"]) if unit.get_progress(): progress = unit.get_progress() if term["field"]=="score_rel": value = Progress.percent(progress) if term["field"]=="score_abs": str_value = Progress.frac(progress) value = str_value[0] else: value = 0 if term["sign"]== "more": if value > term["value"]: return True else: return False if term["sign"]== "more-equals": if value >= term["value"]: return True else: return False if term["sign"]== "less": if value < term["value"]: return True else: return False if term["sign"]== "less-equals": if value <= term["value"]: return True else: return False if term["sign"]== "equals": if value == term["value"]: return True else: return False return error_return
class ProgressTest(unittest.TestCase): ''' Test that basic Progress objects work. A Progress represents a fraction between 0 and 1. ''' not_started = Progress(0, 17) part_done = Progress(2, 6) half_done = Progress(3, 6) also_half_done = Progress(1, 2) done = Progress(7, 7) def test_create_object(self): # These should work: p = Progress(0, 2) p = Progress(1, 2) p = Progress(2, 2) p = Progress(2.5, 5.0) p = Progress(3.7, 12.3333) # These shouldn't self.assertRaises(ValueError, Progress, 0, 0) self.assertRaises(ValueError, Progress, 2, 0) self.assertRaises(ValueError, Progress, 1, -2) self.assertRaises(TypeError, Progress, 0, "all") # check complex numbers just for the heck of it :) self.assertRaises(TypeError, Progress, 2j, 3) def test_clamp(self): self.assertEqual((2, 2), Progress(3, 2).frac()) self.assertEqual((0, 2), Progress(-2, 2).frac()) def test_frac(self): p = Progress(1, 2) (a, b) = p.frac() self.assertEqual(a, 1) self.assertEqual(b, 2) def test_percent(self): self.assertEqual(self.not_started.percent(), 0) self.assertAlmostEqual(self.part_done.percent(), 33.33333333333333) self.assertEqual(self.half_done.percent(), 50) self.assertEqual(self.done.percent(), 100) self.assertEqual( self.half_done.percent(), self.also_half_done.percent()) def test_started(self): self.assertFalse(self.not_started.started()) self.assertTrue(self.part_done.started()) self.assertTrue(self.half_done.started()) self.assertTrue(self.done.started()) def test_inprogress(self): # only true if working on it self.assertFalse(self.done.inprogress()) self.assertFalse(self.not_started.inprogress()) self.assertTrue(self.part_done.inprogress()) self.assertTrue(self.half_done.inprogress()) def test_done(self): self.assertTrue(self.done.done()) self.assertFalse(self.half_done.done()) self.assertFalse(self.not_started.done()) def test_str(self): self.assertEqual(str(self.not_started), "0/17") self.assertEqual(str(self.part_done), "2/6") self.assertEqual(str(self.done), "7/7") def test_ternary_str(self): self.assertEqual(self.not_started.ternary_str(), "none") 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) p2 = Progress(1, 3) p3 = Progress(2, 5) pNone = None add = lambda a, b: Progress.add_counts(a, b).frac() self.assertEqual(add(p, p), (0, 4)) self.assertEqual(add(p, p2), (1, 5)) self.assertEqual(add(p2, p3), (3, 8)) self.assertEqual(add(p2, pNone), p2.frac()) self.assertEqual(add(pNone, p2), p2.frac()) def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' p = Progress(1, 2) p2 = Progress(2, 4) p3 = Progress(1, 2) self.assertTrue(p == p3) self.assertFalse(p == p2) # Check != while we're at it self.assertTrue(p != p2) self.assertFalse(p != p3)
def test_clamp(self): self.assertEqual((2, 2), Progress(3, 2).frac()) self.assertEqual((0, 2), Progress(-2, 2).frac())
class ProgressTest(unittest.TestCase): ''' Test that basic Progress objects work. A Progress represents a fraction between 0 and 1. ''' not_started = Progress(0, 17) part_done = Progress(2, 6) half_done = Progress(3, 6) also_half_done = Progress(1, 2) done = Progress(7, 7) def test_create_object(self): # These should work: prg1 = Progress(0, 2) # pylint: disable=unused-variable prg2 = Progress(1, 2) # pylint: disable=unused-variable prg3 = Progress(2, 2) # pylint: disable=unused-variable prg4 = Progress(2.5, 5.0) # pylint: disable=unused-variable prg5 = Progress(3.7, 12.3333) # pylint: disable=unused-variable # These shouldn't self.assertRaises(ValueError, Progress, 0, 0) self.assertRaises(ValueError, Progress, 2, 0) self.assertRaises(ValueError, Progress, 1, -2) self.assertRaises(TypeError, Progress, 0, "all") # check complex numbers just for the heck of it :) self.assertRaises(TypeError, Progress, 2j, 3) def test_clamp(self): self.assertEqual((2, 2), Progress(3, 2).frac()) self.assertEqual((0, 2), Progress(-2, 2).frac()) def test_frac(self): prg = Progress(1, 2) (a_mem, b_mem) = prg.frac() self.assertEqual(a_mem, 1) self.assertEqual(b_mem, 2) def test_percent(self): self.assertEqual(self.not_started.percent(), 0) self.assertAlmostEqual(self.part_done.percent(), 33.33333333333333) self.assertEqual(self.half_done.percent(), 50) self.assertEqual(self.done.percent(), 100) self.assertEqual(self.half_done.percent(), self.also_half_done.percent()) def test_started(self): self.assertFalse(self.not_started.started()) self.assertTrue(self.part_done.started()) self.assertTrue(self.half_done.started()) self.assertTrue(self.done.started()) def test_inprogress(self): # only true if working on it self.assertFalse(self.done.inprogress()) self.assertFalse(self.not_started.inprogress()) self.assertTrue(self.part_done.inprogress()) self.assertTrue(self.half_done.inprogress()) def test_done(self): self.assertTrue(self.done.done()) self.assertFalse(self.half_done.done()) self.assertFalse(self.not_started.done()) def test_str(self): self.assertEqual(str(self.not_started), "0/17") self.assertEqual(str(self.part_done), "2/6") self.assertEqual(str(self.done), "7/7") self.assertEqual(str(Progress(2.1234, 7)), '2.12/7') self.assertEqual(str(Progress(2.0034, 7)), '2/7') self.assertEqual(str(Progress(0.999, 7)), '1/7') def test_ternary_str(self): self.assertEqual(self.not_started.ternary_str(), "none") 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), "0") def test_to_js_detail_str(self): '''Test the Progress.to_js_detail_str() method''' f = Progress.to_js_detail_str for prg in (self.not_started, self.half_done, self.done): self.assertEqual(f(prg), str(prg)) # But None should be encoded as 0 self.assertEqual(f(None), "0") def test_add(self): '''Test the Progress.add_counts() method''' prg1 = Progress(0, 2) prg2 = Progress(1, 3) prg3 = Progress(2, 5) prg_none = None add = lambda a, b: Progress.add_counts(a, b).frac() self.assertEqual(add(prg1, prg1), (0, 4)) self.assertEqual(add(prg1, prg2), (1, 5)) self.assertEqual(add(prg2, prg3), (3, 8)) self.assertEqual(add(prg2, prg_none), prg2.frac()) self.assertEqual(add(prg_none, prg2), prg2.frac()) def test_equality(self): '''Test that comparing Progress objects for equality works correctly.''' prg1 = Progress(1, 2) prg2 = Progress(2, 4) prg3 = Progress(1, 2) self.assertEqual(prg1, prg3) self.assertNotEqual(prg1, prg2) # Check != while we're at it self.assertNotEqual(prg1, prg2) self.assertEqual(prg1, prg3)