SPRNET-1543 Changed the default behaviour for GetObjectDefinionNames back to not include ancestors, added additional method that allows via bool parmeter to include parent factories. Other areas get the default inlucde where unit tests needed this options. Consumer of GetObjectDefinitionsNames are checked for potential NPE

This commit is contained in:
Thomas Trageser
2013-03-23 18:58:08 +00:00
parent 01b1f57224
commit 4005e9eff6
18 changed files with 295 additions and 81 deletions

View File

@@ -114,6 +114,11 @@ namespace Spring.Context.Support
return null;
}
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
{
return null;
}
public string[] GetObjectDefinitionNames(Type type)
{
return null;

View File

@@ -63,7 +63,7 @@ namespace Spring.Objects.Factory {
protected internal void AssertCount (int count)
{
IList<string> defnames = ListableObjectFactory.GetObjectDefinitionNames();
IList<string> defnames = ListableObjectFactory.GetObjectDefinitionNames(true);
Assert.IsTrue (
defnames.Count == count,
string.Format ("We should have {0} objects, not {1}.", count, defnames.Count));
@@ -78,7 +78,7 @@ namespace Spring.Objects.Factory {
public virtual void AssertTestObjectCount (int count)
{
IList<string> defnames =
ListableObjectFactory.GetObjectNamesForType (typeof (TestObject));
ListableObjectFactory.GetObjectNamesForType(typeof (TestObject));
Assert.IsTrue (
defnames.Count == count,
string.Format ("We should have {0} objects for class {1}, not {2}.", count, typeof (TestObject).FullName, defnames.Count));

View File

@@ -104,7 +104,7 @@ namespace Spring.Objects.Factory.Config
cfg.Location = mockResource;
cfg.ConfigSections = new string[] { "" };
IConfigurableListableObjectFactory mockFactory = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mockFactory.GetObjectDefinitionNames()).Return(new string[] {});
Expect.Call(mockFactory.GetObjectDefinitionNames(false)).Return(new string[] {});
mocks.ReplayAll();
cfg.PostProcessObjectFactory(mockFactory);
@@ -148,8 +148,8 @@ namespace Spring.Objects.Factory.Config
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName)).Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName, false)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -165,6 +165,38 @@ namespace Spring.Objects.Factory.Config
mocks.VerifyAll();
}
[Test]
public void IncludingAncestors()
{
const string defName = "foo";
const string placeholder = "${name}";
MutablePropertyValues pvs = new MutablePropertyValues();
const string theProperty = "name";
pvs.Add(theProperty, placeholder);
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames(true)).Return(new string[] { defName });
Expect.Call(mock.GetObjectDefinition(defName, true)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.IncludeAncestors = true;
NameValueCollection defaultProperties = new NameValueCollection();
const string expectedName = "Rick Evans";
defaultProperties.Add(theProperty, expectedName);
cfg.Properties = defaultProperties;
cfg.PostProcessObjectFactory(mock);
Assert.AreEqual(expectedName, def.PropertyValues.GetPropertyValue(theProperty).Value,
"Property placeholder value was not replaced with the resolved value.");
mocks.VerifyAll();
}
/// <summary>
/// Fallback is the default mode. Check if the PROCESSOR_ARCHITECTURE
/// variable is replaced.
@@ -390,8 +422,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("foo", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
mocks.ReplayAll();
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
@@ -421,8 +453,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("hope.floats", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -451,8 +483,8 @@ namespace Spring.Objects.Factory.Config
properties.Add("hope.floats", expectedName);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof (IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null)).IgnoreArguments().Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string[] {"foo"});
Expect.Call(mock.GetObjectDefinition(null, false)).IgnoreArguments().Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();
@@ -549,8 +581,8 @@ namespace Spring.Objects.Factory.Config
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory) mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames()).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName)).Return(def);
Expect.Call(mock.GetObjectDefinitionNames(false)).Return(new string [] {defName});
Expect.Call(mock.GetObjectDefinition(defName, false)).Return(def);
Expect.Call(delegate { mock.AddEmbeddedValueResolver(null); }).IgnoreArguments();
mocks.ReplayAll();

View File

@@ -20,7 +20,12 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using NUnit.Framework;
using Rhino.Mocks;
using Spring.Context.Support;
using Spring.Objects.Factory.Support;
@@ -33,6 +38,13 @@ namespace Spring.Objects.Factory.Config
[TestFixture]
public class VariablePlaceholderConfigurerTests
{
private MockRepository mocks;
[SetUp]
public void SetUp()
{
mocks = new MockRepository();
}
[Test]
public void ThrowsOnMissingVariableSources()
@@ -276,5 +288,32 @@ namespace Spring.Objects.Factory.Config
Assert.AreEqual("Erich", tb1.Name);
Assert.AreEqual("${nickname}", tb1.Nickname);
}
[Test]
public void InlcludeAncestors()
{
const string defName = "foo";
const string placeholder = "${name}";
MutablePropertyValues pvs = new MutablePropertyValues();
const string theProperty = "name";
pvs.Add(theProperty, placeholder);
RootObjectDefinition def = new RootObjectDefinition(typeof(TestObject), pvs);
IConfigurableListableObjectFactory mock = (IConfigurableListableObjectFactory)mocks.CreateMock(typeof(IConfigurableListableObjectFactory));
Expect.Call(mock.GetObjectDefinitionNames(true)).Return(new string[] { defName });
Expect.Call(mock.GetObjectDefinition(defName, true)).Return(def);
mocks.ReplayAll();
VariablePlaceholderConfigurer vpc = new VariablePlaceholderConfigurer();
vpc.IgnoreUnresolvablePlaceholders = true;
vpc.VariableSource = new DictionaryVariableSource(new string[] { "name", "Erich" });
vpc.IncludeAncestors = true;
vpc.PostProcessObjectFactory(mock);
mocks.VerifyAll();
}
}
}

View File

@@ -1773,6 +1773,66 @@ namespace Spring.Objects.Factory
#endregion
[Test]
public void GetObjectDefinitionNamesOnlyFromChild()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names = child.GetObjectDefinitionNames();
Assert.That(names, Has.Count.EqualTo(1), "GetObjectDefinitionNames() should only return object definition names from this factory");
names = child.GetObjectDefinitionNames(false);
Assert.That(names, Has.Count.EqualTo(1), "GetObjectDefinitionNames(false) should only return object definition names from this factory");
}
[Test]
public void GetObjectDefinitionNamesIncludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names = child.GetObjectDefinitionNames(true);
Assert.That(names, Has.Count.EqualTo(2), "GetObjectDefinitionNames(true) should return object definition names from this factory and parents");
}
[Test]
public void GetObjectDefinitionNamesByTypeExcludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names1 = child.GetObjectDefinitionNames(typeof(NestedTestObject));
var names2 = child.GetObjectDefinitionNames(typeof(TestObject));
Assert.That(names1, Has.Count.EqualTo(1), "Should return only child object definitions");
Assert.That(names2, Has.Count.EqualTo(0), "Should not return the parent object definitions");
}
[Test]
public void GetObjectDefinitionNamesByTypeIncludingParent()
{
DefaultListableObjectFactory parent = new DefaultListableObjectFactory();
parent.RegisterObjectDefinition("testChild", new RootObjectDefinition(typeof(TestObject), null));
DefaultListableObjectFactory child = new DefaultListableObjectFactory(parent);
child.RegisterObjectDefinition("testParent", new RootObjectDefinition(typeof(NestedTestObject), null));
var names1 = child.GetObjectDefinitionNames(typeof(NestedTestObject), true);
var names2 = child.GetObjectDefinitionNames(typeof(TestObject), true);
Assert.That(names1, Has.Count.EqualTo(1), "Should return child object definitions");
Assert.That(names2, Has.Count.EqualTo(1), "Should return the parent object definitions");
}
[Test]
public void GetObjectNamesForTypeFindsFactoryObjects()
{

View File

@@ -46,12 +46,9 @@ namespace Spring.Objects.Factory
[SetUp]
public void SetUp()
{
IObjectFactory grandparent
= new XmlObjectFactory(new ReadOnlyXmlTestResource("root.xml", GetType()));
IObjectFactory parent
= new XmlObjectFactory(new ReadOnlyXmlTestResource("middle.xml", GetType()), grandparent);
IConfigurableListableObjectFactory child
= new XmlObjectFactory(new ReadOnlyXmlTestResource("leaf.xml", GetType()), parent);
IObjectFactory grandparent = new XmlObjectFactory(new ReadOnlyXmlTestResource("root.xml", GetType()));
IObjectFactory parent = new XmlObjectFactory(new ReadOnlyXmlTestResource("middle.xml", GetType()), grandparent);
IConfigurableListableObjectFactory child = new XmlObjectFactory(new ReadOnlyXmlTestResource("leaf.xml", GetType()), parent);
_factory = child;
}

View File

@@ -97,6 +97,11 @@ namespace Spring.Validation
return new List<string>(this.objects.Keys);
}
public IList<string> GetObjectDefinitionNames(bool includeAncestor)
{
return new List<string>(this.objects.Keys);
}
public IList<IObjectDefinition> GetObjectDefinitions()
{
return new List<IObjectDefinition>(this.objects.Values);