From d78e041c2d0712bb86bdedcbf31352378a61b81e Mon Sep 17 00:00:00 2001 From: Victor Shnayder Date: Fri, 12 Oct 2012 15:32:36 -0400 Subject: [PATCH] Testing and small fixes - make chemical_equations_equal return False instead of raising errors. - make tests not choke on unicode - get full coverage --- common/lib/capa/capa/chem/chemcalc.py | 41 ++++++++++++++----------- common/lib/capa/capa/chem/tests.py | 44 +++++++++++++++++++++------ 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/common/lib/capa/capa/chem/chemcalc.py b/common/lib/capa/capa/chem/chemcalc.py index a58a3ac85d..389e688cf4 100644 --- a/common/lib/capa/capa/chem/chemcalc.py +++ b/common/lib/capa/capa/chem/chemcalc.py @@ -218,6 +218,9 @@ def render_to_html(eq): return u'\u2192' if arrow == '<->': return u'\u2194' + + # this won't be reached unless we add more arrow types, but keep it to avoid explosions when + # that happens. return arrow def render_expression(ex): @@ -391,36 +394,40 @@ def chemical_equations_equal(eq1, eq2, exact=False): chemical_equations_equal('H2 + O2 -> H2O2', '2 H2 + 2 O2 -> 2 H2O2', exact=True) -> False - If there's a syntax error, we raise pyparsing.ParseException. + If there's a syntax error, we return False. """ left1, arrow1, right1 = split_on_arrow(eq1) left2, arrow2, right2 = split_on_arrow(eq2) if arrow1 == '' or arrow2 == '': - raise ParseException("Could not find arrow. Legal arrows: {0}".format(ARROWS)) + return False # TODO: may want to be able to give student helpful feedback about why things didn't work. if arrow1 != arrow2: # arrows don't match return False - factor_left = divide_chemical_expression(left1, left2) - if not factor_left: - # left sides don't match - return False + try: + factor_left = divide_chemical_expression(left1, left2) + if not factor_left: + # left sides don't match + return False - factor_right = divide_chemical_expression(right1, right2) - if not factor_right: - # right sides don't match - return False + factor_right = divide_chemical_expression(right1, right2) + if not factor_right: + # right sides don't match + return False - if factor_left != factor_right: - # factors don't match (molecule counts to add up) - return False + if factor_left != factor_right: + # factors don't match (molecule counts to add up) + return False - if exact and factor_left != 1: - # want an exact match. - return False + if exact and factor_left != 1: + # want an exact match. + return False - return True + return True + except ParseException: + # Don't want external users to have to deal with parsing exceptions. Just return False. + return False diff --git a/common/lib/capa/capa/chem/tests.py b/common/lib/capa/capa/chem/tests.py index 9d415ad402..34d903ec1d 100644 --- a/common/lib/capa/capa/chem/tests.py +++ b/common/lib/capa/capa/chem/tests.py @@ -1,3 +1,4 @@ +import codecs from fractions import Fraction from pyparsing import ParseException import unittest @@ -55,15 +56,17 @@ class Test_Compare_Equations(unittest.TestCase): self.assertTrue(chemical_equations_equal('H2 + O2 -> H2O2', 'O2 + H2 -> H2O2', exact=True)) - - def test_syntax_errors(self): - self.assertRaises(ParseException, chemical_equations_equal, - 'H2 + O2 a-> H2O2', - '2O2 + 2H2 -> 2H2O2') - self.assertRaises(ParseException, chemical_equations_equal, - 'H2 + O2 ==> H2O2', # strange arrow - '2O2 + 2H2 -> 2H2O2') + def test_syntax_errors(self): + self.assertFalse(chemical_equations_equal('H2 + O2 a-> H2O2', + '2O2 + 2H2 -> 2H2O2')) + + self.assertFalse(chemical_equations_equal('H2O( -> H2O2', + 'H2O -> H2O2')) + + + self.assertFalse(chemical_equations_equal('H2 + O2 ==> H2O2', # strange arrow + '2O2 + 2H2 -> 2H2O2')) class Test_Compare_Expressions(unittest.TestCase): @@ -294,6 +297,29 @@ class Test_Render_Equations(unittest.TestCase): log(out + ' ------- ' + correct, 'html') self.assertEqual(out, correct) + def test_render_eq1(self): + s = "H^+ + OH^- -> H2O" + out = render_to_html(s) + correct = u'H++OH-\u2192H2O' + log(out + ' ------- ' + correct, 'html') + self.assertEqual(out, correct) + + def test_render_eq2(self): + s = "H^+ + OH^- <-> H2O" + out = render_to_html(s) + correct = u'H++OH-\u2194H2O' + log(out + ' ------- ' + correct, 'html') + self.assertEqual(out, correct) + + + def test_render_eq3(self): + s = "H^+ + OH^- <= H2O" # unsupported arrow + out = render_to_html(s) + correct = u'H^+ + OH^- <= H2O' + log(out + ' ------- ' + correct, 'html') + self.assertEqual(out, correct) + + def suite(): @@ -305,6 +331,6 @@ def suite(): if __name__ == "__main__": local_debug = True - with open('render.html', 'w') as f: + with codecs.open('render.html', 'w', encoding='utf-8') as f: unittest.TextTestRunner(verbosity=2).run(suite()) # open render.html to look at rendered equations