def test_from(caplog): caplog.set_level(logging.DEBUG) test_data = io.StringIO(""" result: from: courses where: {gereqs: {$eq: SPM}} assert: {count(courses): {$gte: 1}} """) area = AreaOfStudy.load(specification=yaml.load(stream=test_data, Loader=yaml.SafeLoader), c=c) transcript = [ course_from_str("CSCI 111", gereqs=['SPM'], term=20081), course_from_str("ASIAN 110"), ] s = next(area.solutions(transcript=transcript, areas=[], exceptions=[])) a = s.audit().result assert len(a.successful_claims) == 1 assert a.successful_claims[0].claim.course.clbid == transcript[0].clbid
def test_count_courses_optimization(): courses = [ course_from_str('A 101'), course_from_str('B 101'), course_from_str('C 101'), ] rule = QueryRule.load(path=[], c=c, data={ 'from': 'courses', 'assert': { 'count(courses)': { '$gte': 2 } }, }) results = list(iterate_item_set(courses, rule=rule)) assert results == [ tuple([courses[0], courses[1]]), tuple([courses[0], courses[2]]), tuple([courses[1], courses[2]]), tuple([courses[0], courses[1], courses[2]]), ]
def test_insertion_on_course_rule(caplog): caplog.set_level(logging.DEBUG) area = AreaOfStudy.load(specification={"result": { "course": "DEPT 345" }}, c=c) exception = load_exception({ "type": "insert", "path": ["$", "*DEPT 345"], "clbid": "1", }) course_a = course_from_str("OTHER 123", clbid="0") course_b = course_from_str("OTHER 234", clbid="1") transcript = [course_a, course_b] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[exception])) assert len(solutions) == 1 result = solutions[0].audit() assert result.ok() is True assert result.was_overridden() is True assert result.claims()[0].claim.course.clbid == course_b.clbid
def test_limits_esth(caplog): spec = """ result: from: courses limit: - at_most: 1 where: $or: - course: {$in: ['STAT 110', 'STAT 212', 'STAT 214']} - ap: {$eq: AP Statistics} assert: {count(courses): {$gte: 2}} """ area = AreaOfStudy.load(specification=yaml.load(stream=spec, Loader=yaml.SafeLoader), c=c) psych_241 = course_from_str("PSYCH 241", clbid="0") stat_212 = course_from_str("STAT 212", clbid="1") ap_stat = course_from_str("STAT 0", name="AP Statistics", course_type="AP", clbid="2") transcript = [psych_241, stat_212, ap_stat] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[])) course_sets = [list(s.solution.output) for s in solutions] assert course_sets == [ [psych_241], [psych_241, stat_212], [psych_241, ap_stat], ]
def test_count_credits_optimizations(): courses = [ course_from_str('A 101', credits=Decimal('0.5')), course_from_str('B 101', credits=Decimal('0.5')), course_from_str('C 101', credits=Decimal('0.5')), ] rule = QueryRule.load(path=[], c=c, data={ 'from': 'courses', 'assert': { 'sum(credits)': { '$gte': 1 } }, }) results = list(iterate_item_set(courses, rule=rule)) assert results == [ tuple([courses[0], courses[1]]), tuple([courses[0], courses[2]]), tuple([courses[1], courses[2]]), tuple([courses[0], courses[1], courses[2]]), ]
def test_multi_insertion_on_query_rule_audit_clause(caplog): caplog.set_level(logging.DEBUG) area = AreaOfStudy.load(specification={ "result": { "from": "courses", "all": [{ "assert": { "count(courses)": { "$gte": 1 } } }], }, }, c=c) exception = load_exception({ "type": "insert", "path": ['$', '.query', '.assertions', '[0]', '.assert'], "clbid": "1", }) exception2 = load_exception({ "type": "insert", "path": ['$', '.query', '.assertions', '[0]', '.assert'], "clbid": "2", }) course_a = course_from_str("DEPT 123", clbid="0") course_b = course_from_str("DEPT 345", clbid="1") course_c = course_from_str("DEPT 234", clbid="2") transcript = [course_a, course_b, course_c] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[exception, exception2])) assert len(solutions) == 7 result = solutions[0].audit() assert result.result.resolved_assertions[0].was_overridden() is False assert result.ok() is True assert result.was_overridden() is False assert result.result.resolved_assertions[0].was_overridden() is False assert set( result.result.resolved_assertions[0].assertion.resolved_items) == set( ['1', '0', '2']) assert result.claims()[0].claim.course.clbid == course_a.clbid assert len(result.claims()) == 1
def test_sum_credits__large(): result = funcs.sum_credits([ course_from_str("MUSIC 111", credits=Decimal('1')), course_from_str("MUSIC 111", credits=Decimal('2')), ]) assert result.value == Decimal('3') assert result.data == (Decimal('1'), Decimal('2')) assert len(result.courses) == 2
def test_sum_credits_from_single_subject__partial(): result = funcs.sum_credits_from_single_subject([ course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("MUSIC 111", credits=Decimal('0.25')), ]) assert result.value == Decimal('0.5') assert result.data == tuple([Decimal('0.25'), Decimal('0.25')]) assert len(result.courses) == 2
def test_average_grades__all_zeroes(): result = funcs.average_grades([ course_from_str("A 100", grade_points=Decimal('0.0'), grade_points_gpa=Decimal('0.0')), course_from_str("B 200", grade_points=Decimal('0.0'), grade_points_gpa=Decimal('0.0')), ]) assert result.value == Decimal('0.0') assert result.data == (Decimal('0.0'), Decimal('0.0')) assert len(result.courses) == 2
def test_count_terms_from_most_common_course__two_sections_same_term(): result = funcs.count_terms_from_most_common_course([ course_from_str("ECON 123", section='A', clbid='123', crsid='1', year='2009', term='3'), course_from_str("ECON 123", section='B', clbid='124', crsid='1', year='2009', term='3'), ]) assert result.value == 1 assert result.data == ('20093',) assert len(result.courses) == 2
def test_sum_credits(): result = funcs.sum_credits([ course_from_str("MUSIC 111", credits=1), course_from_str("ECON 123", credits=1), course_from_str("ECON 125", credits=1), ]) assert result.value == 3 assert result.data == (1, 1, 1) assert len(result.courses) == 3
def test_count_courses__all_same(): result = funcs.count_courses([ course_from_str("ECON 123", clbid='1'), course_from_str("ECON 123", clbid='1'), course_from_str("ECON 123", clbid='1'), ]) assert result.value == 1 assert result.data == tuple(['1']) assert len(result.courses) == 1
def test_count_subjects__several_courses_same_dept(): result = funcs.count_subjects([ course_from_str("ECON 123"), course_from_str("ECON 124"), course_from_str("ECON 125"), ]) assert result.value == 1 assert result.data == ('ECON',) assert len(result.courses) == 1
def test_count_courses__all_different(): result = funcs.count_courses([ course_from_str("ECON 123", clbid='1'), course_from_str("CSCI 124", clbid='2'), course_from_str("ASIAN 125", clbid='3'), ]) assert result.value == 3 assert result.data == ('1', '2', '3') assert len(result.courses) == 3
def test_count_subjects__several_courses(): result = funcs.count_subjects([ course_from_str("ECON 123"), course_from_str("CSCI 124"), course_from_str("ASIAN 125"), ]) assert result.value == 3 assert result.data == ('ASIAN', 'CSCI', 'ECON') assert len(result.courses) == 3
def test_count_terms_from_most_common_course(): result = funcs.count_terms_from_most_common_course([ course_from_str("MUSIC 111", crsid='1', year='2007', term='1'), course_from_str("ECON 123", clbid='b', crsid='2', year='2009', term='1'), course_from_str("ECON 123", clbid='c', crsid='2', year='2009', term='3'), ]) assert result.value == 2 assert result.data == ('20091', '20093') assert len(result.courses) == 2
def test_clause__grade_code(): c = Constants(matriculation_year=2000) clause = load_clause({"grade_code": {"$in": ["P", "IP", "S"]}}, c=c) y_course = course_from_str(s="CSCI 296", grade_code="P") n_course = course_from_str(s="CSCI 296", grade_code="F") assert clause.apply(y_course) is True assert clause.apply(n_course) is False
def test_count_subjects__chbi(): result = funcs.count_subjects([ course_from_str("CH/BI 125"), course_from_str("CH/BI 126"), course_from_str("CH/BI 227"), ]) assert result.value == 2 assert result.data == ('BIO', 'CHEM') assert len(result.courses) == 2
def test_average_credits(): result = funcs.average_credits([ course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("ART 101", credits=Decimal('1')), ]) assert result.value == Decimal('0.4375') assert result.data == (Decimal('0.25'), Decimal('0.25'), Decimal('0.25'), Decimal('1')) assert len(result.courses) == 4
def test_sum_credits__fractional(): result = funcs.sum_credits([ course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("MUSIC 111", credits=Decimal('0.25')), course_from_str("ECON 123", credits=Decimal('0.5')), course_from_str("ECON 125", credits=Decimal('1')), ]) assert result.value == Decimal('2.00') assert result.data == (Decimal('0.25'), Decimal('0.25'), Decimal('0.5'), Decimal('1')) assert len(result.courses) == 4
def __get_data(spec): area = AreaOfStudy.load(specification=yaml.load(stream=io.StringIO(spec), Loader=yaml.SafeLoader), c=c) transcript = [ course_from_str("CSCI 113", gereqs=['SPM'], term=20071), course_from_str("CSCI 112", gereqs=['SPM'], term=20081), course_from_str("CSCI 111", gereqs=['SPM'], term=20091), ] return (area, transcript)
def test_sum_credits__sorts_output(): result = funcs.sum_credits([ course_from_str("MUSIC 111", credits=3), course_from_str("MUSIC 111", credits=2), course_from_str("MUSIC 111", credits=1), ]) assert result.value == 6 # we assert that the output data does not match the input data, but is instead sorted assert result.data == (1, 2, 3) assert sorted(result.data) == sorted([1, 2, 3]) assert len(result.courses) == 3
def test_sum_credits__ignores_zeroes(): result = funcs.sum_credits([ course_from_str("MUSIC 111", credits=0), course_from_str("ECON 123", credits=1), course_from_str("ECON 125", credits=1), ]) assert result.value == 2 assert result.data == (1, 1) # this is where we assert that we ignore 0-credit courses. # if we didn't ignore them, this would report 3 courses. assert len(result.courses) == 2
def test_global_limits(caplog): caplog.set_level(logging.DEBUG) test_data = io.StringIO(""" limit: - at_most: 1 where: {level: {$eq: 200}} - at_most: 1 where: {level: {$eq: 300}} result: from: courses where: {subject: {$eq: BIO}} assert: {count(courses): {$gte: 1}} """) area = AreaOfStudy.load(specification=yaml.load(stream=test_data, Loader=yaml.SafeLoader), c=c) bio_101 = course_from_str("BIO 101") bio_201 = course_from_str("BIO 201") bio_202 = course_from_str("BIO 202") bio_301 = course_from_str("BIO 301") bio_302 = course_from_str("BIO 302") transcript = [bio_101, bio_201, bio_202, bio_301, bio_302] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[])) course_sets = set([frozenset(s.solution.output) for s in solutions]) assert course_sets == set([ frozenset((bio_101, bio_201)), frozenset((bio_101, bio_201, bio_301)), frozenset((bio_101, bio_201, bio_302)), frozenset((bio_101, bio_202)), frozenset((bio_101, bio_202, bio_301)), frozenset((bio_101, bio_202, bio_301)), frozenset((bio_101, bio_202, bio_302)), frozenset((bio_101, bio_301)), frozenset((bio_101, bio_302)), frozenset((bio_101, )), frozenset((bio_201, bio_301)), frozenset((bio_201, bio_302)), frozenset((bio_201, )), frozenset((bio_202, bio_301)), frozenset((bio_202, bio_302)), frozenset((bio_202, )), frozenset((bio_301, )), frozenset((bio_302, )), ])
def test_multi_insertion_on_count_rule__any_with_natural(caplog): caplog.set_level(logging.DEBUG) area = AreaOfStudy.load(specification={ "result": { "any": [ { "course": "DEPT 123" }, ], }, }, c=c) exception = load_exception({ "type": "insert", "path": ['$', '.count'], "clbid": "1", }) exception2 = load_exception({ "type": "insert", "path": ['$', '.count'], "clbid": "2", }) course_a = course_from_str("DEPT 123", clbid="0") course_b = course_from_str("OTHER 234", clbid="1") course_c = course_from_str("OTHER 222", clbid="2") transcript = [course_a, course_b, course_c] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[exception, exception2])) print([s.solution for s in solutions]) assert [[ x.course for x in s.solution.items if isinstance(x, CourseResult) ] for s in solutions] == [['DEPT 123', 'OTHER 234', 'OTHER 222']] assert len(solutions) == 1 result = solutions[0].audit() assert result.result.count == 1 assert result.ok() is True assert result.was_overridden() is False assert result.claims()[0].claim.course.clbid == course_a.clbid assert result.claims()[1].claim.course.clbid == course_b.clbid assert result.claims()[2].claim.course.clbid == course_c.clbid
def test_multi_insertion_on_query_rule(caplog): caplog.set_level(logging.DEBUG) area = AreaOfStudy.load(specification={ "result": { "from": "courses", "where": { "subject": { "$eq": "ABC" } }, "assert": { "count(courses)": { "$gte": 1 } }, }, }, c=c) exception = load_exception({ "type": "insert", "path": ["$", ".query"], "clbid": "0", }) exception2 = load_exception({ "type": "insert", "path": ["$", ".query"], "clbid": "1", }) course_a = course_from_str("OTHER 123", clbid="0") course_b = course_from_str("OTHER 111", clbid="1") transcript = [course_a, course_b] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[exception, exception2])) assert len(solutions) == 1 result = solutions[0].audit() assert result.ok() is True assert result.was_overridden() is False assert result.claims()[0].claim.course.clbid == course_a.clbid assert result.claims()[1].claim.course.clbid == course_b.clbid assert len(result.claims()) == 2
def test_count_subjects__one_course(): result = funcs.count_subjects([ course_from_str("ECON 123"), ]) assert result.value == 1 assert result.data == ('ECON',) assert len(result.courses) == 1
def test_override_on_count_rule_assertion_clause(caplog): caplog.set_level(logging.DEBUG) area = AreaOfStudy.load(specification={ "result": { "all": [{ "course": "DEPT 123" }], "audit": { "assert": { "count(courses)": { "$gte": 1 } } }, }, }, c=c) exception = load_exception({ "type": "override", "path": ['$', '.count', '.audit', '[0]', '.assert'], "status": "pass", }) course_a = course_from_str("DEPT 234", clbid="0") course_b = course_from_str("DEPT 345", clbid="1") transcript = [course_a, course_b] solutions = list( area.solutions(transcript=transcript, areas=[], exceptions=[exception])) assert len(solutions) == 1 result = solutions[0].audit() assert result.result.audits()[0].was_overridden() is True assert result.ok() is False assert result.was_overridden() is False
def test_clauses(caplog): caplog.set_level(logging.DEBUG) c = Constants(matriculation_year=2000) x = load_clause({"attributes": {"$eq": "csci_elective"}}, c=c) expected_single = SingleClause(key="attributes", expected="csci_elective", expected_verbatim="csci_elective", operator=Operator.EqualTo) assert x == expected_single crs = course_from_str(s="CSCI 121", attributes=["csci_elective"]) assert x.apply(crs) is True
def test_clauses_in(caplog): caplog.set_level(logging.DEBUG) c = Constants(matriculation_year=2000) course = course_from_str(s="CSCI 296") values = tuple([296, 298, 396, 398]) x = load_clause({"number": {"$in": values}}, c=c) expected_single = SingleClause(key="number", expected=values, expected_verbatim=values, operator=Operator.In) assert x == expected_single assert x.apply(course) is True