mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-12-02 19:44:02 +08:00
Fixing NilBehavior
--HG-- branch : 1.x
This commit is contained in:
@@ -52,6 +52,7 @@ namespace Orchard.Tests.DisplayManagement {
|
||||
Assert.That(foo.Bar, Is.EqualTo("bar"));
|
||||
Assert.That(foo.Bar == null, Is.False);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Animal : Composite {
|
||||
|
||||
41
src/Orchard.Tests/DisplayManagement/NilTests.cs
Normal file
41
src/Orchard.Tests/DisplayManagement/NilTests.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
using NUnit.Framework;
|
||||
using Orchard.DisplayManagement.Shapes;
|
||||
|
||||
namespace Orchard.Tests.DisplayManagement {
|
||||
[TestFixture]
|
||||
public class NilTests {
|
||||
|
||||
[Test]
|
||||
public void NilShouldEqualToNull() {
|
||||
var nil = Nil.Instance;
|
||||
|
||||
Assert.That(nil == null, Is.True);
|
||||
Assert.That(nil != null, Is.False);
|
||||
|
||||
Assert.That(nil == Nil.Instance, Is.True);
|
||||
Assert.That(nil != Nil.Instance, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NilShouldBeRecursive() {
|
||||
dynamic nil = Nil.Instance;
|
||||
|
||||
Assert.That(nil == null, Is.True);
|
||||
Assert.That(nil.Foo == null, Is.True);
|
||||
Assert.That(nil.Foo.Bar == null, Is.True);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void CallingToStringOnNilShouldReturnEmpty() {
|
||||
var nil = Nil.Instance;
|
||||
Assert.That(nil.ToString(), Is.EqualTo(""));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CallingToStringOnDynamicNilShouldReturnEmpty() {
|
||||
dynamic nil = Nil.Instance;
|
||||
Assert.That(nil.Foo.Bar.ToString(), Is.EqualTo(""));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,10 +71,14 @@ namespace Orchard.Tests.DisplayManagement {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NoneEmptyZonesShouldBeNull() {
|
||||
public void NoneEmptyZonesShouldNotBeNull() {
|
||||
Func<dynamic> factory = () => new Shape();
|
||||
|
||||
dynamic foo = new ZoneHolding(factory);
|
||||
|
||||
Assert.That(foo.Header == null, Is.True);
|
||||
Assert.That(foo.Header != null, Is.False);
|
||||
|
||||
foo.Header.Add("blah");
|
||||
|
||||
Assert.That(foo.Header == null, Is.False);
|
||||
|
||||
@@ -217,6 +217,7 @@
|
||||
<Compile Include="Data\StubLocator.cs" />
|
||||
<Compile Include="DisplayManagement\ArgsUtility.cs" />
|
||||
<Compile Include="DisplayManagement\CompositeTests.cs" />
|
||||
<Compile Include="DisplayManagement\NilTests.cs" />
|
||||
<Compile Include="DisplayManagement\ZoneHoldingTests.cs" />
|
||||
<Compile Include="DisplayManagement\DefaultDisplayManagerTests.cs" />
|
||||
<Compile Include="ContainerTestBase.cs" />
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
return TryGetMemberImpl(binder.Name, out result);
|
||||
}
|
||||
|
||||
protected bool TryGetMemberImpl(string name, out object result) {
|
||||
protected virtual bool TryGetMemberImpl(string name, out object result) {
|
||||
if (_props.Contains(name)) {
|
||||
result = _props[name];
|
||||
return true;
|
||||
@@ -94,14 +94,22 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(Composite a, Nil b) {
|
||||
return ReferenceEquals(a, b) || null == a;
|
||||
}
|
||||
|
||||
public static bool operator !=(Composite a, Nil b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
public IDictionary Properties {
|
||||
get { return _props; }
|
||||
}
|
||||
}
|
||||
|
||||
public class Nil : DynamicObject {
|
||||
static readonly object Singleton = new Nil();
|
||||
public static object Instance { get { return Singleton; } }
|
||||
static readonly Nil Singleton = new Nil();
|
||||
public static Nil Instance { get { return Singleton; } }
|
||||
|
||||
private Nil() {
|
||||
}
|
||||
@@ -116,22 +124,60 @@ namespace Orchard.DisplayManagement.Shapes {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) {
|
||||
result = Nil.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result) {
|
||||
switch (binder.Operation) {
|
||||
case ExpressionType.Equal:
|
||||
result = ReferenceEquals(arg, Nil.Instance) || arg == null;
|
||||
result = ReferenceEquals(arg, Nil.Instance) || (object)arg == null;
|
||||
return true;
|
||||
case ExpressionType.NotEqual:
|
||||
result = !ReferenceEquals(arg, Nil.Instance) && arg != null;
|
||||
result = !ReferenceEquals(arg, Nil.Instance) && (object)arg != null;
|
||||
return true;
|
||||
}
|
||||
|
||||
return base.TryBinaryOperation(binder, arg, out result);
|
||||
}
|
||||
|
||||
public static bool operator ==(Nil a, Nil b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator !=(Nil a, Nil b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool operator ==(Nil a, object b) {
|
||||
return ReferenceEquals(a, b) || (object)b == null;
|
||||
}
|
||||
|
||||
public static bool operator !=(Nil a, object b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ReferenceEquals(obj, Nil.Instance);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override bool TryConvert(ConvertBinder binder, out object result) {
|
||||
result = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Orchard.UI.Zones {
|
||||
public override bool TryGetMember(System.Dynamic.GetMemberBinder binder, out object result) {
|
||||
var name = binder.Name;
|
||||
|
||||
if (!base.TryGetMember(binder, out result) || ((dynamic)result) == null) {
|
||||
if (!base.TryGetMember(binder, out result) || (null == result)) {
|
||||
// substitute nil results with a robot that turns adds a zone on
|
||||
// the parent when .Add is invoked
|
||||
result = new ZoneOnDemand(_zoneFactory, this, name);
|
||||
@@ -67,7 +67,7 @@ namespace Orchard.UI.Zones {
|
||||
return TryGetMemberImpl(binder.Name, out result);
|
||||
}
|
||||
|
||||
private bool TryGetMemberImpl(string name, out object result) {
|
||||
protected override bool TryGetMemberImpl(string name, out object result) {
|
||||
|
||||
var parentMember = ((dynamic)_parent)[name];
|
||||
if (parentMember == null) {
|
||||
@@ -139,18 +139,18 @@ namespace Orchard.UI.Zones {
|
||||
}
|
||||
|
||||
public override bool TryConvert(System.Dynamic.ConvertBinder binder, out object result) {
|
||||
result = null;
|
||||
result = Nil.Instance;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool operator ==(ZoneOnDemand expr, object arg) {
|
||||
public static bool operator ==(ZoneOnDemand a, object b) {
|
||||
// if ZoneOnDemand is compared to null it must return true
|
||||
return arg == null || ReferenceEquals(arg, Nil.Instance);
|
||||
return b == null || ReferenceEquals(b, Nil.Instance);
|
||||
}
|
||||
|
||||
public static bool operator !=(ZoneOnDemand expr, object arg) {
|
||||
public static bool operator !=(ZoneOnDemand a, object b) {
|
||||
// if ZoneOnDemand is compared to null it must return true
|
||||
return arg != null && !ReferenceEquals(arg, Nil.Instance);
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
|
||||
Reference in New Issue
Block a user