<commit_before>#
# unittests for xmodule (and capa)
#
# Note: run this using a like like this:
#
# django-admin.py test --settings=lms.envs.test_ike --pythonpath=. common/lib/xmodule

import unittest
import os

import numpy

import xmodule
import capa.calc as calc
import capa.capa_problem as lcp
from xmodule import graders
from xmodule.graders import Score, aggregate_scores
from nose.plugins.skip import SkipTest

class I4xSystem(object):
    '''
    This is an abstraction such that x_modules can function independent 
    of the courseware (e.g. import into other types of courseware, LMS, 
    or if we want to have a sandbox server for user-contributed content)
    '''
    def __init__(self):
        self.ajax_url = '/'
        self.track_function = lambda x: None
        self.render_function = lambda x: {} # Probably incorrect
        self.exception404 = Exception
        self.DEBUG = True
    def __repr__(self):
        return repr(self.__dict__)
    def __str__(self):
        return str(self.__dict__)

i4xs = I4xSystem()

class ModelsTest(unittest.TestCase):
    def setUp(self):
        pass

    def test_get_module_class(self):
        vc = xmodule.get_module_class('video')
        vc_str = "<class 'xmodule.video_module.Module'>"
        self.assertEqual(str(vc), vc_str)
        video_id = xmodule.get_default_ids()['video']
        self.assertEqual(video_id, 'youtube')

    def test_calc(self):
        variables={'R1':2.0, 'R3':4.0}
        functions={'sin':numpy.sin, 'cos':numpy.cos}

        self.assertTrue(abs(calc.evaluator(variables, functions, "10000||sin(7+5)+0.5356"))<0.01)
        self.assertEqual(calc.evaluator({'R1': 2.0, 'R3':4.0}, {}, "13"), 13)
        self.assertEqual(calc.evaluator(variables, functions, "13"), 13)
        self.assertEqual(calc.evaluator({'a': 2.2997471478310274, 'k': 9, 'm': 8, 'x': 0.66009498411213041}, {}, "5"), 5)
        self.assertEqual(calc.evaluator({},{}, "-1"), -1)
        self.assertEqual(calc.evaluator({},{}, "-0.33"), -.33)
        self.assertEqual(calc.evaluator({},{}, "-.33"), -.33)
        self.assertEqual(calc.evaluator(variables, functions, "R1*R3"), 8.0)
        self.assertTrue(abs(calc.evaluator(variables, functions, "sin(e)-0.41"))<0.01)
        self.assertTrue(abs(calc.evaluator(variables, functions, "k*T/q-0.025"))<0.001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "e^(j*pi)")+1)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "j||1")-0.5-0.5j)<0.00001)
        variables['t'] = 1.0
        self.assertTrue(abs(calc.evaluator(variables, functions, "t")-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "T")-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "t", cs=True)-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "T", cs=True)-298)<0.2)
        exception_happened = False
        try: 
            calc.evaluator({},{}, "5+7 QWSEKO")
        except:
            exception_happened = True
        self.assertTrue(exception_happened)

        try: 
            calc.evaluator({'r1':5},{}, "r1+r2")
        except calc.UndefinedVariable:
            pass
        
        self.assertEqual(calc.evaluator(variables, functions, "r1*r3"), 8.0)

        exception_happened = False
        try: 
            calc.evaluator(variables, functions, "r1*r3", cs=True)
        except:
            exception_happened = True
        self.assertTrue(exception_happened)

#-----------------------------------------------------------------------------
# tests of capa_problem inputtypes

class MultiChoiceTest(unittest.TestCase):
    def test_MC_grade(self):
        multichoice_file = os.path.dirname(__file__)+"/test_files/multichoice.xml"
        test_lcp = lcp.LoncapaProblem(open(multichoice_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'choice_foil3'}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':'choice_foil2'}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')

    def test_MC_bare_grades(self):
        multichoice_file = os.path.dirname(__file__)+"/test_files/multi_bare.xml"
        test_lcp = lcp.LoncapaProblem(open(multichoice_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'choice_2'}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':'choice_1'}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        
    def test_TF_grade(self):
        truefalse_file =  os.path.dirname(__file__)+"/test_files/truefalse.xml"
        test_lcp = lcp.LoncapaProblem(open(truefalse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':['choice_foil2', 'choice_foil1']}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':['choice_foil1']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil1', 'choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil1', 'choice_foil2', 'choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        
class ImageResponseTest(unittest.TestCase):
    def test_ir_grade(self):
        imageresponse_file = os.path.dirname(__file__)+"/test_files/imageresponse.xml"
        test_lcp = lcp.LoncapaProblem(open(imageresponse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'(490,11)-(556,98)',
                           '1_2_2':'(242,202)-(296,276)'}
        test_answers = {'1_2_1':'[500,20]',
                        '1_2_2':'[250,300]',
                        }
        self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_1'), 'correct')
        self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_2'), 'incorrect')
        
class SymbolicResponseTest(unittest.TestCase):
    def test_sr_grade(self):
        # raise SkipTest() # This test fails due to dependencies on a local copy of snuggletex-webapp. Until we have figured that out, we'll just skip this test
        symbolicresponse_file = os.path.dirname(__file__)+"/test_files/symbolicresponse.xml"
        test_lcp = lcp.LoncapaProblem(open(symbolicresponse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'cos(theta)*[[1,0],[0,1]] + i*sin(theta)*[[0,1],[1,0]]',
                           '1_2_1_dynamath': '''
<math xmlns="http://www.w3.org/1998/Math/MathML">
  <mstyle displaystyle="true">
    <mrow>
      <mi>cos</mi>
      <mrow>
        <mo>(</mo>
        <mi>&#x3B8;</mi>
        <mo>)</mo>
      </mrow>
    </mrow>
    <mo>&#x22C5;</mo>
    <mrow>
      <mo>[</mo>
      <mtable>
        <mtr>
          <mtd>
            <mn>1</mn>
          </mtd>
          <mtd>
            <mn>0</mn>
          </mtd><commit_msg>SymbolicResponseTest works if snuggletex war running ; back to skipping it for now<commit_after>#
# unittests for xmodule (and capa)
#
# Note: run this using a like like this:
#
# django-admin.py test --settings=lms.envs.test_ike --pythonpath=. common/lib/xmodule

import unittest
import os

import numpy

import xmodule
import capa.calc as calc
import capa.capa_problem as lcp
from xmodule import graders
from xmodule.graders import Score, aggregate_scores
from nose.plugins.skip import SkipTest

class I4xSystem(object):
    '''
    This is an abstraction such that x_modules can function independent 
    of the courseware (e.g. import into other types of courseware, LMS, 
    or if we want to have a sandbox server for user-contributed content)
    '''
    def __init__(self):
        self.ajax_url = '/'
        self.track_function = lambda x: None
        self.render_function = lambda x: {} # Probably incorrect
        self.exception404 = Exception
        self.DEBUG = True
    def __repr__(self):
        return repr(self.__dict__)
    def __str__(self):
        return str(self.__dict__)

i4xs = I4xSystem()

class ModelsTest(unittest.TestCase):
    def setUp(self):
        pass

    def test_get_module_class(self):
        vc = xmodule.get_module_class('video')
        vc_str = "<class 'xmodule.video_module.Module'>"
        self.assertEqual(str(vc), vc_str)
        video_id = xmodule.get_default_ids()['video']
        self.assertEqual(video_id, 'youtube')

    def test_calc(self):
        variables={'R1':2.0, 'R3':4.0}
        functions={'sin':numpy.sin, 'cos':numpy.cos}

        self.assertTrue(abs(calc.evaluator(variables, functions, "10000||sin(7+5)+0.5356"))<0.01)
        self.assertEqual(calc.evaluator({'R1': 2.0, 'R3':4.0}, {}, "13"), 13)
        self.assertEqual(calc.evaluator(variables, functions, "13"), 13)
        self.assertEqual(calc.evaluator({'a': 2.2997471478310274, 'k': 9, 'm': 8, 'x': 0.66009498411213041}, {}, "5"), 5)
        self.assertEqual(calc.evaluator({},{}, "-1"), -1)
        self.assertEqual(calc.evaluator({},{}, "-0.33"), -.33)
        self.assertEqual(calc.evaluator({},{}, "-.33"), -.33)
        self.assertEqual(calc.evaluator(variables, functions, "R1*R3"), 8.0)
        self.assertTrue(abs(calc.evaluator(variables, functions, "sin(e)-0.41"))<0.01)
        self.assertTrue(abs(calc.evaluator(variables, functions, "k*T/q-0.025"))<0.001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "e^(j*pi)")+1)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "j||1")-0.5-0.5j)<0.00001)
        variables['t'] = 1.0
        self.assertTrue(abs(calc.evaluator(variables, functions, "t")-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "T")-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "t", cs=True)-1.0)<0.00001)
        self.assertTrue(abs(calc.evaluator(variables, functions, "T", cs=True)-298)<0.2)
        exception_happened = False
        try: 
            calc.evaluator({},{}, "5+7 QWSEKO")
        except:
            exception_happened = True
        self.assertTrue(exception_happened)

        try: 
            calc.evaluator({'r1':5},{}, "r1+r2")
        except calc.UndefinedVariable:
            pass
        
        self.assertEqual(calc.evaluator(variables, functions, "r1*r3"), 8.0)

        exception_happened = False
        try: 
            calc.evaluator(variables, functions, "r1*r3", cs=True)
        except:
            exception_happened = True
        self.assertTrue(exception_happened)

#-----------------------------------------------------------------------------
# tests of capa_problem inputtypes

class MultiChoiceTest(unittest.TestCase):
    def test_MC_grade(self):
        multichoice_file = os.path.dirname(__file__)+"/test_files/multichoice.xml"
        test_lcp = lcp.LoncapaProblem(open(multichoice_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'choice_foil3'}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':'choice_foil2'}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')

    def test_MC_bare_grades(self):
        multichoice_file = os.path.dirname(__file__)+"/test_files/multi_bare.xml"
        test_lcp = lcp.LoncapaProblem(open(multichoice_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'choice_2'}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':'choice_1'}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        
    def test_TF_grade(self):
        truefalse_file =  os.path.dirname(__file__)+"/test_files/truefalse.xml"
        test_lcp = lcp.LoncapaProblem(open(truefalse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':['choice_foil2', 'choice_foil1']}
        self.assertEquals(test_lcp.grade_answers(correct_answers).get_correctness('1_2_1'), 'correct')
        false_answers = {'1_2_1':['choice_foil1']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil1', 'choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        false_answers = {'1_2_1':['choice_foil1', 'choice_foil2', 'choice_foil3']}
        self.assertEquals(test_lcp.grade_answers(false_answers).get_correctness('1_2_1'), 'incorrect')
        
class ImageResponseTest(unittest.TestCase):
    def test_ir_grade(self):
        imageresponse_file = os.path.dirname(__file__)+"/test_files/imageresponse.xml"
        test_lcp = lcp.LoncapaProblem(open(imageresponse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'(490,11)-(556,98)',
                           '1_2_2':'(242,202)-(296,276)'}
        test_answers = {'1_2_1':'[500,20]',
                        '1_2_2':'[250,300]',
                        }
        self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_1'), 'correct')
        self.assertEquals(test_lcp.grade_answers(test_answers).get_correctness('1_2_2'), 'incorrect')
        
class SymbolicResponseTest(unittest.TestCase):
    def test_sr_grade(self):
        raise SkipTest() # This test fails due to dependencies on a local copy of snuggletex-webapp. Until we have figured that out, we'll just skip this test
        symbolicresponse_file = os.path.dirname(__file__)+"/test_files/symbolicresponse.xml"
        test_lcp = lcp.LoncapaProblem(open(symbolicresponse_file), '1', system=i4xs)
        correct_answers = {'1_2_1':'cos(theta)*[[1,0],[0,1]] + i*sin(theta)*[[0,1],[1,0]]',
                           '1_2_1_dynamath': '''
<math xmlns="http://www.w3.org/1998/Math/MathML">
  <mstyle displaystyle="true">
    <mrow>
      <mi>cos</mi>
      <mrow>
        <mo>(</mo>
        <mi>&#x3B8;</mi>
        <mo>)</mo>
      </mrow>
    </mrow>
    <mo>&#x22C5;</mo>
    <mrow>
      <mo>[</mo>
      <mtable>
        <mtr>
          <mtd>
            <mn>1</mn>
          </mtd>
          <mtd>
            <mn>0</mn>
          </mtd>
{'fraction_non_alphanumeric': 0.16012473730594537, 'fraction_numerical': 0.04392922513727883, 'mean_word_length': 3.143820224719101, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4981790', 'n_tokens_mistral': 5466, 'n_tokens_neox': 5137, 'n_words': 768}