public void multiple_connections_can_be_added_between_two_valid_nodes_but_only_one_appears() { var g = new AffectedGraph(); g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo2", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); g.AddConnection("bar::foo2", "bar::foo", false); g.AddConnection("bar::foo2", "bar::foo", false); Assert.AreEqual(1, g.AllConnections().Count()); }
public void node_and_direct_test_in_graph() { var graph = new AffectedGraph(); graph.AddNode(new AffectedGraphNode(displayName: "display", isInterface: false, isTest: false, isRootNode: true, name: "A name", fullName: "fullnamecode", assembly: "foo.dll", type: "Type", testDescriptors: new List <TestDescriptor>(), isChange: false, inTestAssembly: false, complexity: 0)); graph.AddNode(new AffectedGraphNode(displayName: "display", isInterface: false, isTest: true, isRootNode: true, name: "A name", fullName: "fullnametest", assembly: "foo.dll", type: "Type", testDescriptors: new List <TestDescriptor>(), isChange: false, inTestAssembly: true, complexity: 0)); graph.AddConnection("fullnamecode", "fullnametest", false); var classifier = new TestPathsGraphRiskClassifier(); Assert.AreEqual(100, classifier.CalculateRiskFor(graph)); }
public void adding_a_null_to_connection_does_not_add_node() { var g = new AffectedGraph(); g.AddConnection("FROM", null, false); Assert.AreEqual(0, g.AllConnections().Count()); }
public void connection_can_be_added_between_same_nodes() { var g = new AffectedGraph(); g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); g.AddConnection("bar::foo", "bar::foo", false); Assert.AreEqual(1, g.AllConnections().Count()); }
public void a_connection_from_a_non_existant_node_does_not_add_connection() { var g = new AffectedGraph(); g.AddNode(new AffectedGraphNode("foo", false, false, false, "name", "bar::foo", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); g.AddConnection("somethingnon-existant", "bar::foo", false); Assert.AreEqual(0, g.AllConnections().Count()); }
public void connections_from_both_graphs_get_added_to_output() { var graph1 = new AffectedGraph(); graph1.AddNode(new AffectedGraphNode("test1", false, false, false, "test", "test123", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); graph1.AddConnection("test123", "test123", false); var graph2 = new AffectedGraph(); graph2.AddNode(new AffectedGraphNode("test12", false, false, false, "test", "test1234", "assembly", "type", new List <TestDescriptor>(), false, false, 0)); graph2.AddConnection("test1234", "test1234", false); var merged = graph1.Merge(graph2); Assert.AreEqual(2, merged.AllConnections().Count()); }
public static AffectedGraph BuildGraphFor(IEnumerable <IEnumerable <string> > paths) { bool first = true; var ret = new AffectedGraph(); foreach (var path in paths) { string last = null; foreach (var node in path) { if (!ret.ContainsNode(node)) { ret.AddNode(new AffectedGraphNode(node, false, false, first, node, node, "", "", new List <TestDescriptor>(), false, false, 0)); first = false; } if (last != null) { ret.AddConnection(last, node, false); } last = node; } } return(ret); }
private void FillAfferentGraph(string fullName, Dictionary<string, bool> cutPoints, AffectedGraph graph, MemberReference parent, int depth, TypeDefinition inheritedTypeContext, bool inVirtual, List<string> breadCrumbs, GenericContext genericContext, bool inSelf) { WriteWalkerDebug(fullName, depth); if (TryBreadCrumbsPrune(fullName, depth, breadCrumbs)) { if (parent != null) { WriteWalkerDebug("truncating but adding connection to " + fullName, depth); graph.AddConnection(parent.GetCacheName(), fullName, false); } return; } breadCrumbs.Add(fullName); if (TryCutPointPrune(fullName, depth, cutPoints)) { if (parent != null) { WriteWalkerDebug("bread crumbs truncating but adding connection to " + fullName, depth); graph.AddConnection(parent.GetCacheName(), fullName, false); } return; } var efferentEntry = _cache.TryGetEfferentCouplingNode(fullName); var afferentEntry = _cache.TryGetEfferentCouplingNode(fullName); MethodDefinition currentDefinition = null; if (efferentEntry != null) { TypeReference parentType = null; if (parent != null) parentType = parent.DeclaringType; var definition = efferentEntry.MemberReference.DeclaringType.ThreadSafeResolve(); if (TryInterfacePrune(fullName, depth, breadCrumbs, efferentEntry, parentType, definition)) return; if (TryInheritancePrune(fullName, depth, breadCrumbs, inVirtual, definition, inheritedTypeContext)) {return;} inheritedTypeContext = GetNewTypeContext(inheritedTypeContext, definition); currentDefinition = efferentEntry.MemberReference as MethodDefinition; if (currentDefinition != null) { if(currentDefinition.DeclaringType == null) {} if (parent is FieldReference && currentDefinition.IsConstructor) { breadCrumbs.Remove(fullName); return; } } } var touse = afferentEntry ?? efferentEntry; WriteWalkerDebug("adding node " + fullName, depth); var newnode = GetGraphNode(fullName, touse, parent == null, false); graph.AddNode(newnode); if (parent != null) { graph.AddConnection(parent.GetCacheName(), newnode.FullName, false); } if(currentDefinition != null) RecurseSynonyms(depth, cutPoints, inheritedTypeContext, currentDefinition, graph, breadCrumbs, genericContext); RecurseAfferentCouplings(fullName, depth, cutPoints, inVirtual, inheritedTypeContext, graph, parent, breadCrumbs, genericContext); breadCrumbs.Remove(fullName); }
private void GetEfferentGraph(string parent, string fullName, IDictionary<string, bool> cutOffs, List<ChangeContext> found, AffectedGraph graph, bool isRootNode, TypeDefinition originalContext) { var entry = _cache.TryGetEfferentCouplingNode(fullName); var afferent = _cache.TryGetAfferentCouplingNode(fullName); if (isRootNode) { entry = entry ?? afferent; found.Add(new ChangeContext(fullName, null)); graph.AddNode(GetGraphNode(fullName, entry, true, true)); if (entry != null && entry.MemberReference != null) { var refer = entry.MemberReference as MethodReference; if (refer != null && _testStrategies.IsTest(refer)) { return; } } } //TODO Greg this hamstrings some stuff but should work better in most cases //I think we only really need statics past here but need to look it over a bit. return; WriteWalkerDebug("checking " + fullName, 0); if (entry == null) { WriteWalkerDebug("efferent entry is null", 0); if (afferent != null && afferent.MemberReference is MethodReference) return; //Leaf node to a method call } if(afferent == null) { WriteWalkerDebug("afferent entry is null", 0); } if (afferent != null) { var memref = afferent.MemberReference as MethodReference; MethodDefinition def = null; if (memref != null) { def = memref.ThreadSafeResolve(); } if (!isRootNode && def != null) { if (def.IsGetter) return; if (def.DeclaringType.IsInterface) return; //don't recurse forward on interface calls if (!def.HasThis) return; } var reference = afferent.MemberReference as FieldReference; //Leaf node to a field reference if (reference != null) { graph.AddNode(GetGraphNode(fullName, afferent, isRootNode, false)); if (parent != null) graph.AddConnection(parent, fullName, true); found.Add(new ChangeContext(fullName, originalContext)); } } if (entry == null) return; graph.AddNode(GetGraphNode(fullName, entry, isRootNode, false)); if (parent != null) graph.AddConnection(parent, fullName, true); foreach (var current in entry.Couplings) { if (cutOffs.ContainsKey(current.To)) continue; if (current.IgnoreWalk) continue; if (current.ActualReference is MethodReference && !current.IsSelfCall) continue; cutOffs.Add(current.To, true); GetEfferentGraph(fullName, current.To, cutOffs, found, graph, false, originalContext); } }