def testInvalidRelationalDependencies(self): schema = Schema() schema.addEntity('A') schema.addEntity('B') schema.addRelationship('AB', ('A', Schema.ONE), ('B', Schema.ONE)) schema.addAttribute('A', 'X') schema.addAttribute('B', 'Y') # Check that entire dependency is canonical (relVar2 has a singleton path) TestUtil.assertRaisesMessage( self, Exception, "Dependency '[B].Y -> [B, AB, A].X' is not canonical", RelationalValidity.checkRelationalDependencyValidity, schema, ParserUtil.parseRelDep('[B].Y -> [B, AB, A].X')) # Check that base items are the same in both paths TestUtil.assertRaisesMessage( self, Exception, "Dependency '[B].Y -> [A].X' has inconsistent base items", RelationalValidity.checkRelationalDependencyValidity, schema, ParserUtil.parseRelDep('[B].Y -> [A].X')) # enforce that the relational variables are checked for consistency against the schema # using RelationalValidity.checkRelationalVariableValidity mockRelVarChecker = MagicMock( wraps=RelationalValidity.checkRelationalVariableValidity) RelationalValidity.checkRelationalDependencyValidity( schema, ParserUtil.parseRelDep('[A, AB, B].Y -> [A].X'), relationalVariableChecker=mockRelVarChecker) self.assertEqual(2, mockRelVarChecker.call_count)
def testRemoveEdgesForDependency(self): schema = Schema() schema.addEntity('A') schema.addAttribute('A', 'A') schema.addAttribute('A', 'B') schema.addAttribute('A', 'C') schema.addAttribute('A', 'D') schema.addAttribute('A', 'E') schema.addAttribute('A', 'F') schema.addAttribute('A', 'G') schema.addAttribute('A', 'H') dependencies = [ '[A].A -> [A].B', '[A].A -> [A].C', '[A].B -> [A].D', '[A].C -> [A].D', '[A].E -> [A].F', '[A].E -> [A].G', '[A].F -> [A].H', '[A].G -> [A].H' ] model = Model(schema, dependencies) agg = AbstractGroundGraph(model, 'A', 0) agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].B -> [A].A')) self.assertEqual(8, len(agg.edges())) agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].A -> [A].B')) self.assertEqual(7, len(agg.edges())) self.assertNotIn( (ParserUtil.parseRelVar('[A].A'), ParserUtil.parseRelVar('[A].B')), agg.edges()) agg.removeEdgesForDependency(ParserUtil.parseRelDep('[A].F -> [A].H')) self.assertEqual(6, len(agg.edges())) self.assertNotIn( (ParserUtil.parseRelVar('[A].F'), ParserUtil.parseRelVar('[A].H')), agg.edges()) schema = Schema() schema.addEntity('A') schema.addEntity('B') schema.addEntity('C') schema.addRelationship('AB', ('A', Schema.MANY), ('B', Schema.MANY)) schema.addRelationship('BC', ('B', Schema.ONE), ('C', Schema.MANY)) schema.addAttribute('A', 'X') schema.addAttribute('B', 'Y') schema.addAttribute('C', 'Z') schema.addAttribute('AB', 'XY') schema.addAttribute('BC', 'YZ') model = Model(schema, [ '[BC, B, AB, A].X -> [BC].YZ', '[AB, B, BC, C].Z -> [AB].XY', '[AB, B, AB, A, AB, B].Y -> [AB].XY' ]) aAGG = AbstractGroundGraph(model, 'A', 6) self.assertEqual(9, len(aAGG.edges())) aAGG.removeEdgesForDependency( ParserUtil.parseRelDep('[BC, B, AB, A].X -> [BC].YZ')) self.assertEqual(7, len(aAGG.edges())) aAGG.removeEdgesForDependency( ParserUtil.parseRelDep('[AB, B, AB, A, AB, B].Y -> [AB].XY')) self.assertEqual(2, len(aAGG.edges()))
def assertAGGEqualNoIntersection(self, schema, actualAgg, expectedRelDepStrs): expectedNodes = [ relVar for relVar in RelationalSpace.getRelationalVariables( schema, actualAgg.hopThreshold, includeExistence=False) if relVar.getBaseItemName() == actualAgg.perspective ] expectedEdges = [(ParserUtil.parseRelDep(depStr).relVar1, ParserUtil.parseRelDep(depStr).relVar2) for depStr in expectedRelDepStrs] TestUtil.assertUnorderedListEqual(self, expectedNodes, actualAgg.nodes()) TestUtil.assertUnorderedListEqual(self, expectedEdges, actualAgg.edges())
def setUndirectedDependencies(self, undirectedDependencyStrs, dependencyChecker=RelationalValidity.checkRelationalDependencyValidity): if not isinstance(undirectedDependencyStrs, collections.Iterable): raise Exception("Undirected dependencies must be an iterable sequence of parseable RelationalDependency " "strings: found {}".format(undirectedDependencyStrs)) undirectedDependencies = [ParserUtil.parseRelDep(depStr) for depStr in undirectedDependencyStrs] # check each undirected dependency for consistency against the schema for undirectedDependency in undirectedDependencies: dependencyChecker(self.schema, undirectedDependency) self.undirectedDependencies = undirectedDependencies self.constructAggsFromDependencies(self.undirectedDependencies, times)
def testParseRelationalDependency(self): relDepStr = '[A].X -> [A].Y' actualRelDep = ParserUtil.parseRelDep(relDepStr) self.assertTrue(isinstance(actualRelDep, RelationalDependency)) self.assertEqual('[A].X', str(actualRelDep.relVar1)) self.assertEqual('[A].Y', str(actualRelDep.relVar2)) self.assertEqual(relDepStr, str(actualRelDep)) relDepStr = '[A, AB, B].Y -> [A, AB].XY' actualRelDep = ParserUtil.parseRelDep(relDepStr) self.assertTrue(isinstance(actualRelDep, RelationalDependency)) self.assertEqual('[A, AB, B].Y', str(actualRelDep.relVar1)) self.assertEqual('[A, AB].XY', str(actualRelDep.relVar2)) self.assertEqual(relDepStr, str(actualRelDep)) relDepStr = '[A, AB, B].Y -> [A, AB].XY' actualRelDepIn = ParserUtil.parseRelDep(relDepStr) actualRelDepOut = ParserUtil.parseRelDep(actualRelDepIn) self.assertEqual(actualRelDepIn, actualRelDepOut) TestUtil.assertRaisesMessage( self, Exception, "relDepStr is not a string or RelationalDependency object", ParserUtil.parseRelDep, None)