def test_normative_stance_no_norm(self): """Verifies function returns False when the Issue has no norm.""" stance = Stance() stance.issue = "decision_analyze_test_no_norm" result = stance_analyze.normative_stance(stance) self.assertFalse(result)
def test_normative_stance_not_in_db(self): """Verifies function returns False when the norm is not in the DB.""" stance = Stance() stance.issue = "I Don't Exist" result = stance_analyze.normative_stance(stance) self.assertFalse(result)
def test_normative_stance_norm_doesnt_match(self): """Verifies function returns False when the stance does not match the norm.""" stance = Stance() stance.issue = "decision_analyze_test_norm" stance.side = outcomes.CON result = stance_analyze.normative_stance(stance) self.assertFalse(result)
def test_collect_normative_stances_no_result(self): """Verifies function return nothing if there are no normative stances.""" agn_norm_stance = Stance() agn_norm_stance.issue = "decision_analyze_test_norm" agn_norm_stance.side = outcomes.CON result = stance_analyze.collect_normative_stances([agn_norm_stance, agn_norm_stance]) self.assertEquals(len(result), 0)
def test_normative_stance_norm_match(self): """Verifies function returns True when the stance matches the norm.""" stance = Stance() stance.issue = "decision_analyze_test_norm" stance.side = outcomes.PRO result = stance_analyze.normative_stance(stance) self.assertTrue(result)
def generate_stance(self, stance_importance, relation_importance): """Generates stances for testing with sort keys""" stance = Stance() stance.importance = stance_importance relation = Relation() relation.importance = relation_importance stance.relation = relation stance.sort_key = stance_sort_key.LOYALTY return stance
def test_collect_normative_stances_no_duplicates(self): """Verifies function return does not contain duplicates.""" stance = Stance() stance.issue = "decision_analyze_test_norm" stance.side = outcomes.PRO result = stance_analyze.collect_normative_stances([stance, stance]) self.assertEquals(len(result), 1) self.assertEquals(result[0], stance)
def generate_collect_type_stance_array(self): """Generates the stance array for the collect_type tests""" stance1 = Stance() stance1.source_db = db_constants.MEMBERS stance2 = Stance() stance1.source_db = db_constants.BILLS stance3 = Stance() stance1.source_db = db_constants.GROUPS return [stance1, stance2, stance3]
def test_explain(self): """ Verifies explain runs if there is a success [aka _explain is implemented].""" stance = Stance() stance.issue = "Something good" stance.side = outcomes.FOR self.decision.for_stances = [stance] self.strategy.run() self.assertTrue(self.strategy._success) self.strategy.explain()
def test_run_success_AGN(self): """ Verifies that run() successfully sets an AGN decision""" stance1 = Stance() stance1.issue = "Something bad" stance1.side = outcomes.AGN self.decision.agn_stances = [stance1] result = self.strategy.run() self.assertTrue(result) self.assertTrue(self.strategy._success) self.assertEquals(self.decision.result, outcomes.AGN) self.assertEquals(self.decision.reason, [stance1])
def test_run_success_FOR(self): """ Verifies that run() successfully sets a FOR decision""" stance = Stance() stance.issue = "Something good" stance.side = outcomes.FOR self.decision.for_stances = [stance] result = self.strategy.run() self.assertTrue(result) self.assertTrue(self.strategy._success) self.assertEquals(self.decision.result, outcomes.FOR) self.assertEquals(self.decision.reason, [stance])
def test__match_stances_helper_extra_stances(self): """ Verifies that extra stances in the filter stances list are not added.""" member = self.generate_member_with_stances() stances = member.credo + member.pro_rel_stances stance = Stance() stance.issue = "Not Found" stance.side = outcomes.PRO stances.append(stance) result = member_analyze._match_stances_helper(member, stances) answer = member.credo + member.pro_rel_stances for entry in result: self.assertTrue(entry in answer)
def test_difference(self): """Verify only the difference of the list is included.""" stance = Stance() stance.issue = "Test" stance.side = outcomes.PRO stance2 = Stance() stance2.issue = "Test" stance2.side = outcomes.PRO stance3 = Stance() stance3.issue = "Test" stance3.side = outcomes.CON eq_fun = lambda stance1, stance2: stance1.match(stance2) result = util.difference([stance, stance2, stance3], [stance, stance2], eq_fun) self.assertEquals(result, [stance3])
def generate_member_with_stances(self): member = Member() credo_stance = Stance() credo_stance.issue = "Credo" credo_stance.side = outcomes.PRO stances_stance = Stance() stances_stance.issue = "Stances" stances_stance.side = outcomes.CON pro_rel_stance = Stance() pro_rel_stance.issue = "Pro-Relation" pro_rel_stance.side = outcomes.PRO member.credo.append(credo_stance) member.stances.append(stances_stance) member.pro_rel_stances.append(pro_rel_stance) return member
def test_collect_normative_stances(self): """Verifies function returns only normative stances.""" stance = Stance() stance.issue = "decision_analyze_test_norm" stance.side = outcomes.PRO agn_norm_stance = Stance() agn_norm_stance.issue = "decision_analyze_test_norm" agn_norm_stance.side = outcomes.CON result = stance_analyze.collect_normative_stances([stance, agn_norm_stance]) self.assertEquals(len(result), 1) self.assertEquals(result[0], stance)
def test_remove_less_important_stances_only_one(self): """ Verifies remove less importance where only one is left.""" stance1 = Stance() stance1.importance = importance.A stance2 = Stance() stance2.importance = importance.B stance3 = Stance() stance3.importance = importance.C answer = [stance1] result = util.remove_less_important_stances([stance1, stance2, stance3]) self.assertEqual(len(result), len(answer)) for stance1, stance2 in zip(result, answer): self.assertEquals(stance1, stance2)
def test_remove_duplicates(self): """Verify only the intersection of the list is included.""" stance = Stance() stance.issue = "Test" stance.side = outcomes.PRO stance2 = Stance() stance2.issue = "Something different" stance2.side = outcomes.PRO data = [stance, stance, stance2, stance2, stance, stance2, stance] result = util.remove_duplicates(data) self.assertEquals(len(result), 2) self.assertTrue(stance in result) self.assertTrue(stance2 in result)
def setUp(self): # This is fake data. Do not use it to make assumptions about how # data will look in the actual system. self.relation = Relation() self.relation.importance = importance.D self.input_hash = {"importance": importance.A, "issue": "CONSTITUTION", "relation": self.relation, "siblings": ["Sib1", "Sib2"], "side": "PRO", "_sort_key": "Some initial random value", "source": "PARRIS", "source_db": "member"} self.input_hash2 = {"importance": importance.A, "issue": "CONSTITUTION", "relation": self.relation, "siblings": ["Sib1", "Sib2"], "side": "PRO", "_sort_key": "Some initial random value", "source": "PARRIS", "source_db": "member"} self.stance = Stance(self.input_hash) self.stance2 = Stance(self.input_hash2)
def test_run_fail(self): """ Verifies that run() doesn't modify the decision upon failure.""" stance = Stance() stance.issue = "Something good" stance.side = outcomes.FOR stance1 = Stance() stance1.issue = "Something bad" stance1.side = outcomes.AGN self.decision.for_stances = [stance] self.decision.agn_stances = [stance1] result = self.strategy.run() self.assertFalse(result) self.assertFalse(self.strategy._success) self.assertEquals(self.decision.result, None) self.assertEquals(self.decision.reason, None)
def generate_stance_array(self): """Generates the stance array for the _compare_stance tests""" stance1 = Stance() stance1.importance = importance.B relation1 = Relation() relation1.importance = importance.C stance1.relation = relation1 stance2 = Stance() stance2.importance = importance.B relation2 = Relation() relation2.importance = importance.A stance2.relation = relation2 stance3 = Stance() stance3.importance = importance.C relation3 = Relation() relation3.importance = importance.B stance3.relation = relation3 stance4 = Stance() stance4.importance = importance.D relation4 = Relation() relation4.importance = importance.A stance4.relation = relation4 return [stance1, stance2, stance3, stance4]
def test_group_stances(self): """Verifies stances are grouped by stance and side.""" stance1 = Stance() stance1.issue = "Apples" stance1.side = outcomes.PRO stance2 = Stance() stance2.issue = "Oranges" stance2.side = outcomes.PRO stance3 = Stance() stance3.issue = "Banana" stance3.side = outcomes.CON stance4 = Stance() stance4.issue = "Apples" stance4.side = outcomes.CON stance5 = Stance() stance5.issue = "Banana" stance5.side = outcomes.CON stance6 = Stance() stance6.issue = "Oranges" stance6.side = outcomes.CON input_list = [stance1, stance2, stance3, stance4, stance5, stance6] correct_list = [stance4, stance1, stance3, stance5, stance6, stance2] stance_analyze.group_stances(input_list) self.assertEquals(input_list, correct_list)
class StanceTest(unittest.TestCase): """ Test suite for Stance.""" def setUp(self): # This is fake data. Do not use it to make assumptions about how # data will look in the actual system. self.relation = Relation() self.relation.importance = importance.D self.input_hash = {"importance": importance.A, "issue": "CONSTITUTION", "relation": self.relation, "siblings": ["Sib1", "Sib2"], "side": "PRO", "_sort_key": "Some initial random value", "source": "PARRIS", "source_db": "member"} self.input_hash2 = {"importance": importance.A, "issue": "CONSTITUTION", "relation": self.relation, "siblings": ["Sib1", "Sib2"], "side": "PRO", "_sort_key": "Some initial random value", "source": "PARRIS", "source_db": "member"} self.stance = Stance(self.input_hash) self.stance2 = Stance(self.input_hash2) def test_init_default(self): """Tests that default values are set for instance variables""" stance = Stance() self.assertEqual(stance.source, None) self.assertEqual(stance.source_db, None) self.assertEqual(stance.issue, None) self.assertEqual(stance.importance, None) self.assertEqual(stance.side, None) self.assertEqual(stance.relation, None) self.assertEqual(stance.siblings, []) self.assertEqual(stance._sort_key, None) def test_init_hash(self): """ Verifies that input data from a hash is properly set.""" stance = Stance(self.input_hash) for key, value in self.input_hash.iteritems(): self.assertEqual(value, stance.__dict__[key]) def test_init_hash_default(self): """ Verifies defaults are still defined when a hash is provided.""" self.input_hash.pop("source") stance = Stance(self.input_hash) for key, value in self.input_hash.iteritems(): self.assertEqual(value, stance.__dict__[key]) self.assertEqual(stance.source, None) def test_sort_key_undefined(self): """When sort_key is undefined, verifies the stance's importance is returned.""" self.stance._sort_key = None self.assertEqual(self.stance.sort_key, self.stance.importance) def test_sort_key_equity(self): """Verifies that the EQUITY sort key is set properly.""" self.stance.sort_key = stance_sort_key.EQUITY self.assertEqual(self.stance.sort_key, [self.stance.importance, self.relation.importance]) def test_sort_key_loyalty(self): """Verifies that the LOYALTY sort key is set properly.""" self.stance.sort_key = stance_sort_key.LOYALTY self.assertEqual(self.stance.sort_key, [self.relation.importance, self.stance.importance]) def test_sort_key_no_relation(self): """Verifies relation_import is set to B if no relation provided.""" self.stance.relation = None self.stance.sort_key = stance_sort_key.LOYALTY self.assertEqual(self.stance.sort_key, [importance.B, self.stance.importance]) def test_sort_key_no_relation_importance(self): """Verifies relation_import is set to B if there is no relation importance.""" self.relation.importance = None self.stance.sort_key = stance_sort_key.LOYALTY self.assertEqual(self.stance.sort_key, [importance.B, self.stance.importance]) def test_sort_key_unknown(self): """Verifies sort_key can gracefully handle an unknown option.""" self.stance._sort_key = None self.stance.sort_key = "I am an unknown sort key" self.assertEqual(self.stance.sort_key, self.stance.importance) def test_match_true(self): """Verifies that match returns true properly.""" self.stance2.importance = importance.Z self.assertTrue(self.stance.match(self.stance2)) def test_total_match_bad_side(self): """Verifies that match returns false when the sides differ.""" self.stance2.side = "Something else" self.assertFalse(self.stance.total_match(self.stance2)) def test_total_match_bad_issue(self): """Verifies that match returns false when the issues differ.""" self.stance2.issue = "Something else" self.assertFalse(self.stance.total_match(self.stance2)) def test_total_match_true(self): """Verifies that total match returns true properly.""" self.assertTrue(self.stance.total_match(self.stance2)) def test_total_match_false(self): """Verifies that total match returns false properly.""" self.stance2.importance = importance.Z self.assertFalse(self.stance.total_match(self.stance2))
def test_match_stances_agn(self): """ Verifies the returned stances are sorted by importance.""" member = Member() member.stance_sort_key = stance_sort_key.EQUITY credo_stance = Stance() credo_stance.issue = "Credo" credo_stance.side = outcomes.PRO credo_stance.importance = importance.B stances_stance1 = Stance() stances_stance1.issue = "Stances" stances_stance1.side = outcomes.CON stances_stance1.importance = importance.D stances_stance2 = Stance() stances_stance2.issue = "An Outcomes" stances_stance2.side = outcomes.PRO stances_stance2.importance = importance.A pro_rel_stance = Stance() pro_rel_stance.issue = "Pro-Relation" pro_rel_stance.side = outcomes.PRO pro_rel_stance.importance = importance.C member.credo.append(credo_stance) member.stances.append(stances_stance1) member.stances.append(stances_stance2) member.pro_rel_stances.append(pro_rel_stance) bill = Bill() bill.stances_for = member.credo + member.stances bill.stances_agn = member.pro_rel_stances result = member_analyze.match_stances(member, bill, outcomes.FOR) sorted_answer = [stances_stance2, credo_stance, stances_stance1] self.assertEqual(result, sorted_answer)
def _compare_stances(fors, agns): """This functions compares the stances to see which side has the most compelling reasons. It does so by checking which side has the largest number and most important stances supporting it. Arguments: fors: the list of stances supporting the bill to decide on agns: the list of stances against the bill to decide on Returns: A list containing the strongest arguments for or against the bill. Returns an empty list if both sides are equally compelling. Notes: Both lists are first sorted by importance. Then, it goes through and compares each stance. If one list runs out before the other, the longest list is considered to have the most compelling stances. If one list is found to have a stance of stronger importance than the other on a give iteration of the for loop, that list is considered to be the most important and is chosen. """ fors.sort(key=lambda stance: stance.sort_key, reverse=True) agns.sort(key=lambda stance: stance.sort_key, reverse=True) # base_stance is used in the enum. Once an array runs out of stances, # this will be mapped to be compared to the stances in the other list. Since # Z is not an importance actually assigned in the DB, this is guaranteed to # fail so that the longer list will be detected as the winner. # # The sort key is also needed to properly set the default. It will take the # source key from whichever array will last longer. This will ensure that # the stance is less than the next key it will be compared to. temp_stance = None if fors and len(fors) > len(agns): temp_stance = fors[0] elif agns and len(agns) > len(fors): temp_stance = agns[0] base_stance = Stance() base_stance.importance = importance.Z base_stance.sort_key = temp_stance._sort_key if temp_stance else None enum = enumerate(itertools.izip_longest(fors, agns, fillvalue=base_stance)) for index, (a_for, an_agn) in enum: if a_for.sort_key > an_agn.sort_key: result = ResultData() result.outcome = outcomes.FOR result.data = util.remove_less_important_stances(fors[index:]) logger.LOGGER.info("MI stance is FOR the bill.") return result if an_agn.sort_key > a_for.sort_key: result = ResultData() result.outcome = outcomes.AGN result.data = util.remove_less_important_stances(agns[index:]) logger.LOGGER.info("MI stance is AGN the bill.") return result logger.LOGGER.info("MI stance is neutral on the bill.") return None