def test_unmessaged_tifa(self): clear_report() contextualize_report('import random\nrandom') verify() tifa_analysis() final = simple.resolve() self.assertEqual(SUCCESS_MESSAGE, final.title+"\n"+final.message)
def test_copy(self): contextualize_report("for item in item_list:\n" " if item < 0:\n" " n = n + item\n" " i = i + 1\n" "n = 0") match01 = find_match("for _item_ in ___:\n" " __expr__") map_size01 = len(match01.mappings.keys()) match02 = find_match("___ = _item_ + 1", use_previous=match01) map_size02 = len(match01.mappings.keys()) match03 = find_match("___ = _item_ + ___", use_previous=match01) map_size03 = len(match01.mappings.keys()) map_size03_2 = len(match03.mappings.keys()) match04 = find_match("___ = _item_ + 1") match05 = find_match("___ = _item_ + ___") map_size05 = len(match05.mappings.keys()) self.assertTrue(map_size01 == map_size02 == map_size03) self.assertNotEqual(map_size03, map_size03_2) self.assertNotEqual(map_size03_2, map_size05) self.assertFalse(match02) self.assertTrue(match03) self.assertTrue(match04)
def test_aug_assignment(self): contextualize_report( "magnitudes = [1.5, 1.9, 4.3, 2.1, 2.0, 3.6, 0.5, 2.5, 1.9, 4.0, 3.8, 0.7, 2.2, 5.1, 1.6]\n" "count = 0\n" "for item in magnitudes:\n" " if item > 2.0:\n" " count = count + 1\n" "print(count)") match = find_matches("for ___ in ___:\n" " __exp__\n" "print(_var_)")[0] self.assertTrue(match["__exp__"].find_matches(match["_var_"].id)) contextualize_report( "magnitudes = [1.5, 1.9, 4.3, 2.1, 2.0, 3.6, 0.5, 2.5, 1.9, 4.0, 3.8, 0.7, 2.2, 5.1, 1.6]\n" "count = 0\n" "for item in magnitudes:\n" " if item > 2.0:\n" " count += 1\n" "print(count)") match = find_matches("for ___ in ___:\n" " __exp__\n" "print(_var_)")[0] m__exp__ = match["__exp__"] submatches = m__exp__.find_matches(match["_var_"].id, check_meta=False) self.assertTrue(submatches)
def test_hidden_error(self): clear_report() contextualize_report('import pedal') verify() tifa_analysis() final = simple.resolve() self.assertNotEqual("No errors reported.", final.message)
def test_sectional_success(self): clear_report() contextualize_report('a=0\n##### Part 1\nprint("A")\n##### Part 2\nprint("B")') separate_into_sections(independent=True) # Part 0 verify() commands.clear_sandbox() commands.run() # Part 1 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Part 2 next_section() verify() commands.clear_sandbox() commands.run() give_partial(.2) # Resolve everything finals = sectional.resolve() self.assertEqual("""# Global FeedbackSourceSection Feedback separated into groups # 1 Complete Great work! # 2 Complete Great work!""", "\n".join(f"# {g.section_number if g is not None else 'Global'}\n{f.title}\n{f.message}" for g, f in finals.items()))
def test_sections_syntax_errors(self): contextualize_report( dedent(''' NAMES = [____, ____] ##### Part 1 a = 0 print(a) ##### Part 2 Syntax Error! ##### Part 3 Runtime Error ''')) separate_into_sections(independent=True) check_section_exists(3) self.assertEqual(get_all_feedback()[0].label, "FeedbackSourceSection") next_section() verify_section() self.assertEqual(get_all_feedback()[1].label, "FeedbackSourceSection") next_section() verify_section() feedback = get_all_feedback() self.assertTrue(feedback) self.assertEqual(feedback[3].label, "syntax_error") print(feedback[0].location) self.assertEqual(feedback[3].location.line, 7)
def test_cait_get_match_names(self): contextualize_report("for item in item_list:\n" " if item < 0:\n" " n = n + item\n" " i = i + 1\n" "n = 0") match = find_match("___ = _item_ + 1") self.assertEqual(match.names(), {'_item_': 'i'})
def test_parse_program(self): # noinspection PyBroadException try: parse_program() self.assertTrue(False, "Program did not throw exception") except Exception: self.assertTrue(True, "Should NOT FAIL") contextualize_report("fun = 1 + 0") parse_program() self.assertTrue('cait' in MAIN_REPORT, "No parsing happened")
def test_runtime_suppression(self): clear_report() contextualize_report('import json\njson.loads("0")+"1"') verify() tifa_analysis() commands.run() suppress("Runtime") final = simple.resolve() self.assertEqual(Feedback.CATEGORIES.COMPLETE, final.category) self.assertEqual(SUCCESS_TEXT, final.message)
def test_empty(self): clear_report() contextualize_report(' ') verify() tifa_analysis() commands.run() final = simple.resolve() self.assertEqual(Feedback.CATEGORIES.SYNTAX, final.category) self.assertEqual("No Source Code", final.title) self.assertEqual("Source code file is blank.", final.message)
def test_success_suppression(self): clear_report() contextualize_report('a=0\na') verify() tifa_analysis() set_success() suppress(label='set_success') final = simple.resolve() self.assertEqual(Feedback.CATEGORIES.COMPLETE, final.category) self.assertEqual(SUCCESS_MESSAGE, final.title+"\n"+final.message)
def test_success(self): clear_report() contextualize_report('a=0\na') verify() tifa_analysis() set_success() final = simple.resolve() self.assertEqual(Feedback.CATEGORIES.COMPLETE, final.category) self.assertEqual("Complete", final.title) self.assertEqual("Great work!", final.message)
def test_bad_recursion(self): contextualize_report(""" def to_pig_latin(str): first = str[0] str = str[1:] str = str + first + "ay" to_pig_latin("hello")""") commands.run() commands.call('to_pig_latin', 'test', threaded=True) self.assertNotIsInstance(commands.get_exception(), RecursionError)
def test_analyzer_suppression(self): clear_report() contextualize_report('1+"Hello"') verify() tifa_analysis() commands.run() suppress("analyzer") final = simple.resolve() self.assertEqual("runtime", final.category) self.assertEqual("Type Error", final.title)
def __enter__(self): clear_report(report=self.report) contextualize_report(self.code, report=self.report) verify(report=self.report) if self.run_tifa: tifa_analysis(report=self.report) # TODO: Clean this up self.student = get_sandbox(self.report) self.report['sandbox']['sandbox'].tracer_style = self.tracer_style commands.run() return self
def test_cait_node_is_method(self): contextualize_report("class Dog:\n def bark(self):\n pass\ndef dogs_bark(alod):\n pass") ast = parse_program() functions = ast.find_all('FunctionDef') self.assertTrue(functions[0].is_method()) self.assertFalse(functions[1].is_method()) classes = ast.find_all('ClassDef') self.assertFalse(classes[0].is_method()) passes = ast.find_all('Pass') self.assertFalse(passes[0].is_method()) self.assertFalse(passes[1].is_method())
def test_coverage(self): test_filename = here + '_sandbox_test_coverage.py' with open(test_filename) as student_file: student_code = student_file.read() contextualize_report(student_code) student = Sandbox() student.tracer_style = 'coverage' student.run(student_code, filename=test_filename) self.assertIsNone(student.exception) self.assertEqual(student.trace.pc_covered, 80.0) self.assertEqual(student.trace.lines, {1, 2, 4, 7, 10, 11, 12, 13})
def test_coverage(self): test_filename = here + '_sandbox_test_coverage.py' with open(test_filename) as student_file: student_code = student_file.read() contextualize_report(student_code) student = Sandbox() student.tracer_style = 'native' student.run(student_code, filename=test_filename) self.assertIsNone(student.exception) #self.assertEqual(round(student.trace.pc_covered), 85) self.assertEqual(student.trace.lines, [1, 2, 3, 4, 6, 9, 12, 16, 14, 15, 17])
def test_matplotlib(self): student_code = dedent(''' import matplotlib.pyplot as plt plt.plot([1,2,3]) plt.title("My line plot") plt.show() ''') contextualize_report(student_code) student = run(student_code, filename='student.py') self.assertIn('plotting', dir(student.modules)) plt = student.modules.plotting self.assertEqual(len(plt.plots), 1)
def test_catches_blank_files(self): contextualize_report('') verify() feedback = get_all_feedback() self.assertTrue(feedback) self.assertEqual(feedback[0].label, 'blank_source') contextualize_report(' \n\n\n \n\n\n ') verify() feedback = get_all_feedback() self.assertTrue(feedback) self.assertEqual(feedback[0].label, 'blank_source')
def test_find_matches_expr2(self): contextualize_report('for prop_report in crime_reports:\n' ' total_prop= total_prop + prop_report["Property Crime"]\n' ' count_prop= count_prop +1\n' 'average_property = total_prop/count_prop\n' 'for violent_report in crime_reports:\n' ' total_viol= total_viol + violent_report["Violent Crime"]\n' ' count_viol= count_viol +1\n' 'average_violent= total_viol/count_viol\n') matches = find_matches("for ___ in __exp__:\n" " pass") self.assertEqual(4, len(matches))
def test_class_Names(self): contextualize_report("class myClass:\n" " def f(self):\n" " return 'hello world'") parse_program() matches = find_matches("class myClass:\n\tpass") matches_wildcard = find_matches("class _name_:\n\tpass") self.assertTrue(len(matches) == 1, "exact class name matching not working") self.assertTrue(len(matches_wildcard) == 1, "wild card class name matching not working") # Added functionality for matching class names var = matches_wildcard[0]["_name_"] self.assertTrue(var.id == "myClass", "is: '{}' instead of Name".format(var.id))
def test_match_root(self): contextualize_report("for item in item_list:\n" " if item < 0:\n" " n = n + item\n" "n = 0") match01 = find_match("for ___ in ___:\n" " __expr__") match02 = find_match("_var_ = 0") match03 = find_match("_var_ = _var_ + _item_") root01 = match01.match_root.tree_id root02 = match02.match_root.tree_id root03 = match03.match_root.tree_id self.assertTrue(root01 < root02) self.assertTrue(root01 < root03)
def test_combining_scores_complex(self): clear_report() contextualize_report('a=0\nprint(a)') # These are added feedback(activate=True, valence=1, score="+4%", category='instructor') # These are skipped feedback(activate=False, valence=1, score="+5%", category='instructor') # These are skipped feedback(activate=True, valence=-1, score="+8%", category='instructor') # These are added feedback(activate=False, valence=-1, score="+7%", category='instructor') # Calculate final result final = simple.resolve() self.assertEqual(.11, final.score)
def test_find_matches(self): contextualize_report("fun = 1 + 1\nfun2 = 2 + 2") parse_program() matches = find_matches("_var_ = __expr__") self.assertIsInstance(matches, list, "find_matches did not return a list") self.assertIsInstance(matches[0], AstMap, "find_matches does not contain an AstMap") self.assertEqual(len(matches), 2, "find_matches does not return the correct number of matches") contextualize_report("for 'fun' in ___:" "if ___:\n" " pass") matches = find_matches("for ___ in ___:\n" " pass") self.assertFalse(matches, "find matches should have misparsed and returned False, but returned True instead")
def test_function_recursion(self): contextualize_report("def recursive(item):\n" " if item < 0:\n" " return 0\n" " else:" " return recursive(item - 1)") matches = find_matches("def _recur_(_var_):\n" " __exp__") for match in matches: __exp__ = match["__exp__"] _recur_ = match["_recur_"] _var_ = match["_var_"] self.assertTrue(__exp__.find_matches("{func}()".format(func=_recur_.id)), "couldn't find recursive function call")
def test_matplotlib_commands(self): student_code = dedent(''' import matplotlib.pyplot as plt plt.plot([1,2,3]) plt.title("My line plot") plt.show() plt.hist([1,2,3]) plt.show() ''') contextualize_report(student_code) student = commands.run() print(student) plt2 = student.modules.plotting self.assertEqual(len(plt2.plots), 2)
def test_no_more_input(self): contextualize_report('def x():') verify() feedback = get_all_feedback() self.assertTrue(feedback) self.assertEqual(feedback[0].label, 'syntax_error') self.assertEqual( feedback[0].message, """Bad syntax on line 1 The traceback was: Line 1 of file answer.py def x(): Suggestion: Check line 1, the line before it, and the line after it.""")
def test_attribute_names(self): contextualize_report("import weather\n" "weather_reports = get_weather('Data')\n" "weather_reports = weather.get_weather['Data']\n" "total = 0\n" "for weather in weather_reports:\n" " total = total + weather\n" "print(total)") my_match1 = find_matches("_var_._attr_[__str__]") self.assertTrue(len(my_match1) == 1, "couldn't find attr func access") self.assertTrue(my_match1[0]['_attr_'].id == "get_weather", "'{}' instead of 'get_weather'".format( my_match1[0]['_attr_'].id)) my_match2 = find_matches("_var_.___[__str__]") self.assertTrue(len(my_match2) == 1, "couldn't wild card attribute access")
def test_damaged_sections(self): contextualize_report( dedent(''' NAMES = [____, ____] ##### Part 1 a = 0 print(a) ##### Part 2 Syntax Error! #### Part 3 Runtime Error ''')) verify() separate_into_sections() check_section_exists(3) feedback = get_all_feedback() self.assertTrue(feedback) self.assertTrue(feedback[0].label, "incorrect_number_of_sections")