public void List_OnProperty_isCalled_forEachElement_but_doesNotRecurse_simple_types() { var victim = new ListVictim { PropIntList = new List <int> { 11, 22 } }; var type = victim.GetType(); var callCounts = new Dictionary <string, int> { { ".Root", 0 }, { "PropIntList[0]", 0 }, { "PropIntList[1]", 0 } }; // the calls for the list field and each of its elements A.CallTo(() => listener.OnProperty(GetProp(type, "PropIntList"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; if (ctx.CurrentDepth == 0) { callCounts[".Root"]++; return; } // for the individual elements Assert.Equal(1, ctx.CurrentDepth); callCounts[ctx.BreadcrumbAsString]++; }) .Returns(new SimpleInstanceListenerOnFieldOrPropResult { DoContinueRecursion = true }); Traverser.TraverseInstance(victim, 5, listener); A.CallTo(() => listener.OnField( A <FieldInfo> .That.Not.Matches(x => x == GetField(type, "FieldList")), A <Func <object> > ._, A <IReadOnlyInstanceTraversalContext> ._) ).MustNotHaveHappened(); // all "methods" should have been called exactly once foreach (var(key, value) in callCounts) { // this sillyness provides us with a hint for which thing was not called as expected Assert.Equal($"{key}=1", $"{key}={value}"); } }
public void List_OnProperty_isNotCalled_forEachElement_becauseOnPropertyReturnsFalse() { var victim = new ListVictim { PropIntList = new List <int> { 11, 22 } }; var type = victim.GetType(); var callCounts = new Dictionary <string, int> { { ".Root", 0 }, { "PropIntList[0]", 0 }, { "PropIntList[1]", 0 } }; // the calls for the list field and each of its elements A.CallTo(() => listener.OnProperty(GetProp(type, "PropIntList"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; if (ctx.CurrentDepth == 0) { callCounts[".Root"]++; return; } // for the individual elements Assert.Equal(1, ctx.CurrentDepth); callCounts[ctx.BreadcrumbAsString]++; }) .Returns(new SimpleInstanceListenerOnFieldOrPropResult { DoContinueRecursion = false }); // do not traverse further down this path Traverser.TraverseInstance(victim, 5, listener); A.CallTo(() => listener.OnField( A <FieldInfo> .That.Not.Matches(x => x == GetField(type, "FieldList")), A <Func <object> > ._, A <IReadOnlyInstanceTraversalContext> ._) ).MustNotHaveHappened(); Assert.Equal(1, callCounts[".Root"]); Assert.Equal(0, callCounts["PropIntList[0]"]); Assert.Equal(0, callCounts["PropIntList[1]"]); }
public void List_OnProperty_isCalled_forEachElement_andRecurses() { var one = new InnocentBystander(); var two = new InnocentBystander(); var three = new InnocentBystander(); var victim = new ListVictim { PropList = new List <InnocentBystander> { one, two, three } }; var type = victim.GetType(); var complexType = typeof(InnocentBystander); var callCounts = new Dictionary <string, int> { { ".Root", 0 }, { "PropList[0]", 0 }, { "PropList[0].FieldString", 0 }, { "PropList[1]", 0 }, { "PropList[1].FieldString", 0 }, { "PropList[2]", 0 }, { "PropList[2].FieldString", 0 } }; // the calls for the list field and each of its elements A.CallTo(() => listener.OnProperty(GetProp(type, "PropList"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; if (ctx.CurrentDepth == 0) { callCounts[".Root"]++; return; } // for the individual elements Assert.Equal(1, ctx.CurrentDepth); callCounts[ctx.BreadcrumbAsString]++; }); // the calls for the recursion of each list element A.CallTo(() => listener.OnField(GetField(complexType, "FieldString"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; Assert.Equal(1, ctx.CurrentDepth); callCounts[$"{ctx.BreadcrumbAsString}.FieldString"]++; }); Traverser.TraverseInstance(victim, 5, listener); // all "methods" should have been called exactly once foreach (var(key, value) in callCounts) { // this sillyness provides us with a hint for which thing was not called as expected Assert.Equal($"{key}=1", $"{key}={value}"); } }
public void List_OnField_isNotCalled_forEachElement_becauseOnFieldReturnsFalse() { var one = new InnocentBystander(); var two = new InnocentBystander(); var three = new InnocentBystander(); var victim = new ListVictim { FieldList = new List <InnocentBystander> { one, two, three } }; var type = victim.GetType(); var complexType = typeof(InnocentBystander); var callCounts = new Dictionary <string, int> { { ".Root", 0 }, { "FieldList[0]", 0 }, { "FieldList[0].FieldString", 0 }, { "FieldList[1]", 0 }, { "FieldList[1].FieldString", 0 }, { "FieldList[2]", 0 }, { "FieldList[2].FieldString", 0 } }; // the calls for the list field and each of its elements A.CallTo(() => listener.OnField(GetField(type, "FieldList"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; if (ctx.CurrentDepth == 0) { callCounts[".Root"]++; return; } // for the individual elements Assert.Equal(1, ctx.CurrentDepth); callCounts[ctx.BreadcrumbAsString]++; }) .Returns(new SimpleInstanceListenerOnFieldOrPropResult { DoContinueRecursion = false }); // do not traverse further down this path // the calls for the recursion of each list element A.CallTo(() => listener.OnField(GetField(complexType, "FieldString"), A <Func <object> > ._, A <InstanceTraversalContext> ._)) .Invokes(x => { var ctx = (InstanceTraversalContext)x.Arguments[2]; Assert.Equal(1, ctx.CurrentDepth); callCounts[$"{ctx.BreadcrumbAsString}.FieldString"]++; }) .Returns(new SimpleInstanceListenerOnFieldOrPropResult { DoContinueRecursion = true }); Traverser.TraverseInstance(victim, 5, listener); Assert.Equal(1, callCounts[".Root"]); Assert.Equal(0, callCounts["FieldList[0]"]); Assert.Equal(0, callCounts["FieldList[0].FieldString"]); Assert.Equal(0, callCounts["FieldList[1]"]); Assert.Equal(0, callCounts["FieldList[1].FieldString"]); Assert.Equal(0, callCounts["FieldList[2]"]); Assert.Equal(0, callCounts["FieldList[2].FieldString"]); }