From: <pa...@us...> - 2011-04-25 05:57:53
|
Revision: 5758 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5758&view=rev Author: patearl Date: 2011-04-25 05:57:46 +0000 (Mon, 25 Apr 2011) Log Message: ----------- Linq: More tests related to NH-2583, thanks to Harald Mueller. Modified Paths: -------------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/Domain.cs trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingNotAndDeMorganFixture.cs trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj Added Paths: ----------- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingMoreOperatorsFixture.cs Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/Domain.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/Domain.cs 2011-04-25 05:55:52 UTC (rev 5757) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/Domain.cs 2011-04-25 05:57:46 UTC (rev 5758) @@ -1,261 +1,300 @@ -namespace NHibernate.Test.NHSpecificTest.NH2583 -{ - public class MyRef1 - { - private static int _idCt = 1000; - private int _id; - - public MyRef1() - { - _id = ++_idCt; - } - - public virtual int Id { - get { return _id; } - set { _id = value; } - } - - public virtual int? I1 { get; set; } - public virtual int I2 { get; set; } - public virtual int I3 { get; set; } - - public virtual MyRef2 BO2 { get; set; } - public virtual MyRef3 BO3 { get; set; } - - public virtual MyRef2 GetOrCreateBO2(ISession s) - { - if (BO2 == null) - { - BO2 = new MyRef2(); - s.Save(BO2); - } - return BO2; - } - - public virtual MyRef3 GetOrCreateBO3(ISession s) - { - if (BO3 == null) - { - BO3 = new MyRef3(); - s.Save(BO3); - } - return BO3; - } - } - - public class MyRef2 - { - private static int _idCt = 1000; - private int _id; - - public MyRef2() - { - _id = ++_idCt; - } - - public virtual int Id { - get { return _id; } - set { _id = value; } - } - - public virtual int? J1 { get; set; } - public virtual int J2 { get; set; } - public virtual int J3 { get; set; } - } - - public class MyRef3 - { - private static int _idCt = 3000; - private int _id; - - public MyRef3() - { - _id = ++_idCt; - } - - public virtual int Id { - get { return _id; } - set { _id = value; } - } - - public virtual int L1 { get; set; } - } - - public enum Ignore { Ignore } - public enum TK { Zero, One } - public enum TBO1_I { Null, Zero, One } - public enum TBO2_J { Null, Zero, One } - public enum TBO1_BO2_J { Null, BO1, Zero, One } - public enum TBO1_BO3_L { Null, BO1, Zero, One } - - public class MyBO - { - private static int _idCt = 0; - private int _id; - - public MyBO() - { - _id = ++_idCt; - } - - public virtual int Id { - get { return _id; } - set { _id = value; } - } - - public virtual string Name { get; set; } - public virtual MyBO LeftSon { get; set; } - public virtual MyBO RightSon { get; set; } - public virtual MyRef1 BO1 { get; set; } - public virtual MyRef1 OtherBO1 { get; set; } - public virtual MyRef2 BO2 { get; set; } - public virtual int? K1 { get; set; } - public virtual int K2 { get; set; } - public virtual int K3 { get; set; } - - private MyRef1 GetOrCreateBO1(ISession s) - { - if (BO1 == null) - { - BO1 = new MyRef1(); - s.Save(BO1); - } - return BO1; - } - - private MyRef2 GetOrCreateBO2(ISession s) - { - if (BO2 == null) - { - BO2 = new MyRef2(); - s.Save(BO2); - } - return BO2; - } - - public static void SetK1(MyBO bo, ISession s, TK value) - { - bo.K1 = value == TK.One ? 1 : 0; - } - - public static void SetK2(MyBO bo, ISession s, TK value) - { - bo.K2 = value == TK.One ? 1 : 0; - } - - public static void SetK3(MyBO bo, ISession s, TK value) - { - bo.K3 = value == TK.One ? 1 : 0; - } - - private static void SetBO1_I(MyBO bo, ISession s, TBO1_I value, System.Action<MyRef1, int> set) - { - switch (value) - { - case TBO1_I.Null: - bo.BO1 = null; - break; - case TBO1_I.One: - set(bo.GetOrCreateBO1(s), 1); - break; - case TBO1_I.Zero: - set(bo.GetOrCreateBO1(s), 0); - break; - } - } - - public static void SetBO1_I1(MyBO bo, ISession s, TBO1_I value) - { - SetBO1_I(bo, s, value, (b, i) => b.I1 = i); - } - - public static void SetBO1_I2(MyBO bo, ISession s, TBO1_I value) - { - SetBO1_I(bo, s, value, (b, i) => b.I2 = i); - } - - public static void SetBO1_I3(MyBO bo, ISession s, TBO1_I value) - { - SetBO1_I(bo, s, value, (b, i) => b.I3 = i); - } - - private static void SetBO2_J(MyBO bo, ISession s, TBO2_J value, System.Action<MyRef2, int> set) - { - switch (value) - { - case TBO2_J.Null: - bo.BO2 = null; - break; - case TBO2_J.One: - set(bo.GetOrCreateBO2(s), 1); - break; - case TBO2_J.Zero: - set(bo.GetOrCreateBO2(s), 0); - break; - } - } - - public static void SetBO2_J1(MyBO bo, ISession s, TBO2_J value) - { - SetBO2_J(bo, s, value, (b, i) => b.J1 = i); - } - - public static void SetBO2_J2(MyBO bo, ISession s, TBO2_J value) - { - SetBO2_J(bo, s, value, (b, i) => b.J2 = i); - } - - public static void SetBO2_J3(MyBO bo, ISession s, TBO2_J value) - { - SetBO2_J(bo, s, value, (b, i) => b.J3 = i); - } - - private static void SetBO1_BO2_J(MyBO bo, ISession s, TBO1_BO2_J value, System.Action<MyRef2, int> set) - { - switch (value) - { - case TBO1_BO2_J.Null: - bo.BO1 = null; - break; - case TBO1_BO2_J.BO1: - bo.GetOrCreateBO1(s).BO2 = null; - break; - case TBO1_BO2_J.Zero: - set(bo.GetOrCreateBO1(s).GetOrCreateBO2(s), 0); - break; - case TBO1_BO2_J.One: - set(bo.GetOrCreateBO1(s).GetOrCreateBO2(s), 1); - break; - } - } - - public static void SetBO1_BO2_J1(MyBO bo, ISession s, TBO1_BO2_J value) - { - SetBO1_BO2_J(bo, s, value, (b, i) => b.J1 = i); - } - - public static void Set_BO1_BO2_J2(MyBO bo, ISession s, TBO1_BO2_J value) - { - SetBO1_BO2_J(bo, s, value, (b, i) => b.J2 = i); - } - - public static void SetBO1_BO3_L1(MyBO bo, ISession s, TBO1_BO3_L value) - { - switch (value) - { - case TBO1_BO3_L.Null: - bo.BO1 = null; - break; - case TBO1_BO3_L.BO1: - bo.GetOrCreateBO1(s).BO3 = null; - break; - case TBO1_BO3_L.Zero: - bo.GetOrCreateBO1(s).GetOrCreateBO3(s).L1 = 0; - break; - case TBO1_BO3_L.One: - bo.GetOrCreateBO1(s).GetOrCreateBO3(s).L1 = 1; - break; - } - } - } -} +using System; + +namespace NHibernate.Test.NHSpecificTest.NH2583 +{ + public class MyRef1 + { + private static int _idCt = 1000; + private int _id; + + public MyRef1() + { + _id = ++_idCt; + } + + public virtual int Id + { + get { return _id; } + set { _id = value; } + } + + public virtual int? I1 { get; set; } + public virtual int I2 { get; set; } + public virtual int I3 { get; set; } + + public virtual MyRef2 BO2 { get; set; } + public virtual MyRef3 BO3 { get; set; } + + public virtual MyRef2 GetOrCreateBO2(ISession s) + { + if (BO2 == null) + { + BO2 = new MyRef2(); + s.Save(BO2); + } + return BO2; + } + + public virtual MyRef3 GetOrCreateBO3(ISession s) + { + if (BO3 == null) + { + BO3 = new MyRef3(); + s.Save(BO3); + } + return BO3; + } + } + + public class MyRef2 + { + private static int _idCt = 1000; + private int _id; + + public MyRef2() + { + _id = ++_idCt; + } + + public virtual int Id + { + get { return _id; } + set { _id = value; } + } + + public virtual int? J1 { get; set; } + public virtual int J2 { get; set; } + public virtual int J3 { get; set; } + } + + public class MyRef3 + { + private static int _idCt = 3000; + private int _id; + + public MyRef3() + { + _id = ++_idCt; + } + + public virtual int Id + { + get { return _id; } + set { _id = value; } + } + + public virtual int L1 { get; set; } + } + + public enum Ignore { Ignore } + public enum TK { ValueNull, Zero, One } + public enum TBO1_I { Null, ValueNull, Zero, One } + public enum TBO2_J { Null, ValueNull, Zero, One } + public enum TBO1_BO2_J { Null, BO1, ValueNull, Zero, One } + public enum TBO1_BO3_L { Null, BO1, ValueNull, Zero, One } + + public class MyBO + { + private static int _idCt = 0; + private int _id; + + public MyBO() + { + _id = ++_idCt; + } + + public virtual int Id + { + get { return _id; } + set { _id = value; } + } + + public virtual string Name { get; set; } + public virtual MyBO LeftSon { get; set; } + public virtual MyBO RightSon { get; set; } + public virtual MyRef1 BO1 { get; set; } + public virtual MyRef1 OtherBO1 { get; set; } + public virtual MyRef2 BO2 { get; set; } + public virtual int? K1 { get; set; } + public virtual int K2 { get; set; } + public virtual int K3 { get; set; } + + private MyRef1 GetOrCreateBO1(ISession s) + { + if (BO1 == null) + { + BO1 = new MyRef1(); + s.Save(BO1); + } + return BO1; + } + + private MyRef2 GetOrCreateBO2(ISession s) + { + if (BO2 == null) + { + BO2 = new MyRef2(); + s.Save(BO2); + } + return BO2; + } + + public static void SetK1(MyBO bo, ISession s, TK value) + { + switch (value) + { + case TK.ValueNull: + bo.K1 = null; + break; + case TK.Zero: + bo.K1 = 0; + break; + case TK.One: + bo.K1 = 1; + break; + default: + throw new Exception("Value " + value + " not handled in code"); + } + } + + public static void SetK2(MyBO bo, ISession s, TK value) + { + bo.K2 = value == TK.One ? 1 : 0; + } + + public static void SetK3(MyBO bo, ISession s, TK value) + { + bo.K3 = value == TK.One ? 1 : 0; + } + + private static void SetBO1_I(MyBO bo, ISession s, TBO1_I value, Action<MyRef1, int?> set) + { + switch (value) + { + case TBO1_I.Null: + bo.BO1 = null; + break; + case TBO1_I.ValueNull: + set(bo.GetOrCreateBO1(s), null); + break; + case TBO1_I.Zero: + set(bo.GetOrCreateBO1(s), 0); + break; + case TBO1_I.One: + set(bo.GetOrCreateBO1(s), 1); + break; + default: + throw new Exception("Value " + value + " not handled in code"); + } + } + + public static void SetBO1_I1(MyBO bo, ISession s, TBO1_I value) + { + SetBO1_I(bo, s, value, (b, i) => b.I1 = i); + } + + public static void SetBO1_I2(MyBO bo, ISession s, TBO1_I value) + { + SetBO1_I(bo, s, value, (b, i) => b.I2 = i ?? 0); + } + + public static void SetBO1_I3(MyBO bo, ISession s, TBO1_I value) + { + SetBO1_I(bo, s, value, (b, i) => b.I3 = i ?? 0); + } + + private static void SetBO2_J(MyBO bo, ISession s, TBO2_J value, Action<MyRef2, int?> set) + { + switch (value) + { + case TBO2_J.Null: + bo.BO2 = null; + break; + case TBO2_J.ValueNull: + set(bo.GetOrCreateBO2(s), null); + break; + case TBO2_J.Zero: + set(bo.GetOrCreateBO2(s), 0); + break; + case TBO2_J.One: + set(bo.GetOrCreateBO2(s), 1); + break; + default: + throw new Exception("Value " + value + " not handled in code"); + } + } + + public static void SetBO2_J1(MyBO bo, ISession s, TBO2_J value) + { + SetBO2_J(bo, s, value, (b, i) => b.J1 = i); + } + + public static void SetBO2_J2(MyBO bo, ISession s, TBO2_J value) + { + SetBO2_J(bo, s, value, (b, i) => b.J2 = i ?? 0); + } + + public static void SetBO2_J3(MyBO bo, ISession s, TBO2_J value) + { + SetBO2_J(bo, s, value, (b, i) => b.J3 = i ?? 0); + } + + private static void SetBO1_BO2_J(MyBO bo, ISession s, TBO1_BO2_J value, Action<MyRef2, int?> set) + { + switch (value) + { + case TBO1_BO2_J.Null: + bo.BO1 = null; + break; + case TBO1_BO2_J.BO1: + bo.GetOrCreateBO1(s).BO2 = null; + break; + case TBO1_BO2_J.ValueNull: + set(bo.GetOrCreateBO1(s).GetOrCreateBO2(s), null); + break; + case TBO1_BO2_J.Zero: + set(bo.GetOrCreateBO1(s).GetOrCreateBO2(s), 0); + break; + case TBO1_BO2_J.One: + set(bo.GetOrCreateBO1(s).GetOrCreateBO2(s), 1); + break; + default: + throw new Exception("Value " + value + " not handled in code"); + } + } + + public static void SetBO1_BO2_J1(MyBO bo, ISession s, TBO1_BO2_J value) + { + SetBO1_BO2_J(bo, s, value, (b, i) => b.J1 = i); + } + + public static void Set_BO1_BO2_J2(MyBO bo, ISession s, TBO1_BO2_J value) + { + SetBO1_BO2_J(bo, s, value, (b, i) => b.J2 = i ?? 0); + } + + public static void SetBO1_BO3_L1(MyBO bo, ISession s, TBO1_BO3_L value) + { + switch (value) + { + case TBO1_BO3_L.Null: + bo.BO1 = null; + break; + case TBO1_BO3_L.BO1: + bo.GetOrCreateBO1(s).BO3 = null; + break; + case TBO1_BO3_L.ValueNull: + bo.GetOrCreateBO1(s).GetOrCreateBO3(s).L1 = 0; // L1 is int, not int? + break; + case TBO1_BO3_L.Zero: + bo.GetOrCreateBO1(s).GetOrCreateBO3(s).L1 = 0; + break; + case TBO1_BO3_L.One: + bo.GetOrCreateBO1(s).GetOrCreateBO3(s).L1 = 1; + break; + default: + throw new Exception("Value " + value + " not handled in code"); + } + } + } +} Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingMoreOperatorsFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingMoreOperatorsFixture.cs (rev 0) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingMoreOperatorsFixture.cs 2011-04-25 05:57:46 UTC (rev 5758) @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2583 +{ + public class MassTestingMoreOperatorsFixture : AbstractMassTestingFixture + { + protected override int TestAndAssert(Expression<Func<MyBO, bool>> condition, ISession session, IEnumerable<int> expectedIds) + { + IQueryable<int?> result = session.Query<MyBO>().Where(condition).Select(bo => (int?)bo.BO1.Id); + + var forceDBRun = result.ToList(); + + IEnumerable<int> resultNullTo0 = forceDBRun.Select(i => i ?? 0); + + var expectedBO1Ids = session.Query<MyBO>().Where(bo => expectedIds.Contains(bo.Id)).Select(bo => bo.BO1 == null ? 0 : bo.BO1.Id).ToList(); + AreEqual(expectedBO1Ids, resultNullTo0.ToArray()); + + // Unused result. + return -1; + } + + // Condition pattern: (A && B) && (C || D) SELECT E + + [Test] + public void TestNestedPlus() + { + RunTest(x => (x.K1 + x.K2) + x.K2 == null || (x.K1 + x.K2) + x.K2 == null, + Setters<TK, TK>(MyBO.SetK1, MyBO.SetK2)); + } + + [Test] + public void TestNestedPlusBehindNot() + { + RunTest(x => !((x.K1 + x.K2) + x.K2 != null), + Setters<TK, TK>(MyBO.SetK1, MyBO.SetK2)); + } + + [Test] + public void TestNestedPlusBehindNotAnd() + { + RunTest(x => !((x.K1 + x.K2) + x.K2 != null && (x.K1 + x.K2) + x.K2 != null), + Setters<TK, TK>(MyBO.SetK1, MyBO.SetK2)); + } + + [Test] + public void TestNestedPlusBehindNotOr() + { + RunTest(x => !((x.K1 + x.K2) + x.K2 != null || (x.K1 + x.K2) + x.K2 != null), + Setters<TK, TK>(MyBO.SetK1, MyBO.SetK2)); + } + + [Test] + public void TestNestedPlusBehindOrNav() + { + RunTest(x => (x.BO1.I1 + x.BO1.I2) + x.BO1.I2 == null || (x.BO1.I1 + x.BO1.I2) + x.BO1.I2 == null, + Setters<TBO1_I, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO1_I2)); + } + [Test] + public void TestNestedPlusBehindNotNav() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO1.I2 != null), + Setters<TBO1_I, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO1_I2)); + } + [Test] + public void TestNestedPlusBehindNotAndNav() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO1.I2 != null && (x.BO1.I1 + x.BO1.I2) + x.BO1.I2 != null), + Setters<TBO1_I, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO1_I2)); + } + [Test] + public void TestNestedPlusBehindNotOrNav() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO1.I2 != null || (x.BO1.I1 + x.BO1.I2) + x.BO1.I2 != null), + Setters<TBO1_I, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO1_I2)); + } + + + [Test] + public void TestNestedPlusBehindOrNav2() + { + RunTest(x => (x.BO1.I1 + x.BO1.I2) + x.BO1.I2 == null || (x.BO2.J1 + x.BO2.J2) + x.BO2.J2 == null, + Setters<TBO1_I, TBO1_I, TBO2_J, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO1_I2, MyBO.SetBO2_J1, MyBO.SetBO2_J2)); + } + [Test] + public void TestNestedPlusBehindNotOrNav2() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO1.I2 == null || (x.BO2.J1 + x.BO2.J2) + x.BO2.J2 == null), + Setters<TBO1_I, TBO1_I, TBO2_J, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO1_I2, MyBO.SetBO2_J1, MyBO.SetBO2_J2)); + } + [Test] + public void TestNestedPlusBehindNotAndNav2() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO1.I2 == null && (x.BO2.J1 + x.BO2.J2) + x.BO2.J2 == null), + Setters<TBO1_I, TBO1_I, TBO2_J, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO1_I2, MyBO.SetBO2_J1, MyBO.SetBO2_J2)); + } + + [Test] + public void TestNestedPlusBehindOrNav3() + { + RunTest(x => (x.BO1.I1 + x.BO1.I2) + x.BO2.J2 == null || (x.BO2.J1 + x.BO2.J2) + x.BO1.I2 == null, + Setters<TBO1_I, TBO2_J, TBO2_J, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO2_J2, MyBO.SetBO2_J1, MyBO.SetBO1_I2)); + } + [Test] + public void TestNestedPlusBehindNotOrNav3() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO2.J2 == null || (x.BO2.J1 + x.BO2.J2) + x.BO1.I2 == null), + Setters<TBO1_I, TBO2_J, TBO2_J, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO2_J2, MyBO.SetBO2_J1, MyBO.SetBO1_I2)); + } + [Test] + public void TestNestedPlusBehindNotAndNav3() + { + RunTest(x => !((x.BO1.I1 + x.BO1.I2) + x.BO2.J2 == null && (x.BO2.J1 + x.BO2.J2) + x.BO1.I2 == null), + Setters<TBO1_I, TBO2_J, TBO2_J, TBO1_I>(MyBO.SetBO1_I1, MyBO.SetBO2_J2, MyBO.SetBO2_J1, MyBO.SetBO1_I2)); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingNotAndDeMorganFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingNotAndDeMorganFixture.cs 2011-04-25 05:55:52 UTC (rev 5757) +++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH2583/MassTestingNotAndDeMorganFixture.cs 2011-04-25 05:57:46 UTC (rev 5758) @@ -1,91 +1,126 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using NHibernate.Linq; -using NUnit.Framework; - -namespace NHibernate.Test.NHSpecificTest.NH2583 -{ - public class MassTestingNotAndDeMorganFixture : AbstractMassTestingFixture - { - protected override int TestAndAssert(Expression<Func<MyBO, bool>> condition, ISession session, IEnumerable<int> expectedIds) - { - var result = session.Query<MyBO>().Where(condition); - AreEqual(expectedIds, result.Select(bo => bo.Id).ToArray()); - return expectedIds.Count(); - } - - [Test] - public void Test_NotUnequalIsTheSameAsEqual() - { - int r1 = RunTest(x => !(x.BO1.I1 != 1), - Setters<TBO1_I>(MyBO.SetBO1_I1)); - int r2 = RunTest(x => x.BO1.I1 == 1, - Setters<TBO1_I>(MyBO.SetBO1_I1)); - Assert.AreEqual(r1, r2); - Assert.Greater(r1, 0); - - r1 = RunTest(x => !(x.BO1.I1 != 1), - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - r2 = RunTest(x => x.BO1.I1 == 1, - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - Assert.AreEqual(r1, r2); - Assert.Greater(r1, 0); - } - - [Test] - public void Test_NotEqualIsTheSameAsNotequal() - { - int r1 = RunTest(x => !(x.BO1.I1 == 1), - Setters<TBO1_I>(MyBO.SetBO1_I1)); - // ... is the same as ... - int r2 = RunTest(x => x.BO1.I1 != 1, - Setters<TBO1_I>(MyBO.SetBO1_I1)); - Assert.AreEqual(r1, r2); - Assert.Greater(r1, 0); - } - - [Test] - public void Test_DeMorganNotAnd() - { - // BO1.I1 BO2.J1 x.BO1.I1 != 1 x.BO2.J1 != 1 && ! Result (3v-->2v) Linq2Obj - // null null n n n n f - // null 0 n t n n f - // null 1 n f f t t - // 0 null t n n n f - // 0 0 t t t f f f - // 0 1 t f f t t t - // 1 null f n f t t - // 1 0 f t f t t t - // 1 1 f f f t t t - - RunTest(x => !(x.BO1.I1 != 1 && x.BO2.J1 != 1), - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - } - - [Test] - public void Test_DeMorganNotOr() - { - int r1 = RunTest(x => !(x.BO1.I1 != 1 || x.BO2.J1 != 1), - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - int r2 = RunTest(x => !(x.BO1.I1 != 1) && !(x.BO2.J1 != 1), - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - int r3 = RunTest(x => x.BO1.I1 == 1 && x.BO2.J1 == 1, - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - Assert.AreEqual(r1, r2); - Assert.AreEqual(r2, r3); - Assert.Greater(r1, 0); - } - - [Test] - public void Test_NotNotCanBeEliminated() - { - int r1 = RunTest(x => !(!(x.BO1.I1 != 1 && x.BO2.J1 != 1)), - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - int r2 = RunTest(x => x.BO1.I1 != 1 && x.BO2.J1 != 1, - Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); - Assert.AreEqual(r1, r2); - } - } -} +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH2583 +{ + public class MassTestingNotAndDeMorganFixture : AbstractMassTestingFixture + { + protected override int TestAndAssert(Expression<Func<MyBO, bool>> condition, ISession session, IEnumerable<int> expectedIds) + { + var result = session.Query<MyBO>().Where(condition); + AreEqual(expectedIds, result.Select(bo => bo.Id).ToArray()); + return expectedIds.Count(); + } + + [Test] + public void Test_NotUnequalIsTheSameAsEqual() + { + int r1 = RunTest(x => !(x.BO1.I1 != 1), + Setters<TBO1_I>(MyBO.SetBO1_I1)); + int r2 = RunTest(x => x.BO1.I1 == 1, + Setters<TBO1_I>(MyBO.SetBO1_I1)); + Assert.AreEqual(r1, r2); + Assert.Greater(r1, 0); + + r1 = RunTest(x => !(x.BO1.I1 != 1), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + r2 = RunTest(x => x.BO1.I1 == 1, + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + Assert.AreEqual(r1, r2); + Assert.Greater(r1, 0); + } + + [Test] + public void Test_NotEqualIsTheSameAsNotequal() + { + // Already the following yields different results for I1 == null even though + // it does NOT throw an exception in Linq2Objects: + // ... RunTest(x => x.BO1.I1 != 1, ...); + // * In C# logic, we get null != 1 <=> true + // * In SQL logic, we get null != 1 <=> logical-null => false + + // To exclude this case, we can either make it false in C# ... + int r1 = RunTest(x => x.BO1.I1 != null && x.BO1.I1 != 1, + Setters<TBO1_I>(MyBO.SetBO1_I1)); + // ... or force it to true in SQL + int r2 = RunTest(x => x.BO1.I1 == null || x.BO1.I1 != 1, + Setters<TBO1_I>(MyBO.SetBO1_I1)); + + // Also the following condition yields different results for I1 == null even + // though it does NOT throw an exception in Linq2Objects: + // ... RunTest(x => !(x.BO1.I1 == 1), ...); + // * In C# logic, we get !(null == 1) <=> !(false) <=> true + // * In SQL logic, we get !(null == 1) <=> !(logical-null) <=> logical-null => false + + // Again, to exclude this case, we can either make the inner part true in C# ... + int r3 = RunTest(x => !(x.BO1.I1 == null || x.BO1.I1 == 1), + Setters<TBO1_I>(MyBO.SetBO1_I1)); + // ... or force it to false in SQL: + int r4 = RunTest(x => !(x.BO1.I1 != null && x.BO1.I1 == 1), + Setters<TBO1_I>(MyBO.SetBO1_I1)); + + Assert.Greater(r1, 0); + Assert.Greater(r2, 0); + + // We also expect the !(==) versions to return the same result as the != versions. + Assert.AreEqual(r1, r3); + Assert.AreEqual(r2, r4); + } + + [Test] + public void Test_DeMorganNotAnd() + { + // BO1.I1 BO2.J1 x.BO1.I1 != 1 x.BO2.J1 != 1 && ! Result (3v-->2v) Linq2Obj + // null null n n n n f + // null 0 n t n n f + // null 1 n f f t t + // 0 null t n n n f + // 0 0 t t t f f f + // 0 1 t f f t t t + // 1 null f n f t t + // 1 0 f t f t t t + // 1 1 f f f t t t + + RunTest(x => !(x.BO1.I1 != 1 && x.BO2.J1 != 1), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + } + + [Test] + public void Test_DeMorganNotOr() + { + int r1 = RunTest(x => !(x.BO1.I1 != 1 || x.BO2.J1 != 1), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + int r2 = RunTest(x => !(x.BO1.I1 != 1) && !(x.BO2.J1 != 1), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + int r3 = RunTest(x => x.BO1.I1 == 1 && x.BO2.J1 == 1, + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + Assert.AreEqual(r1, r2); + Assert.AreEqual(r2, r3); + Assert.Greater(r1, 0); + } + + [Test] + public void Test_NotNotCanBeEliminated() + { + // The following condition does *not* return the same values if I1 and/or J1 are + // null in Linq2Objects and in Nhib.Linq: + // x => x.BO1.I1 != 1 && x.BO2.J1 != 1, + // First, assume I1 == null and J1 == 0: + // * In C# (Linq2Objects), we get null != 1 && 0 != 1 <=> true && true <=> true + // * In SQL (NHib.Linq), we get null != 1 && <=> logical-null && true <=> logical-null => false + // For I1 == 0 and J1 == null we get the same problem, as the condition is symmetric. + + // To repair this, we force "SQL" to true for nulls: + int r1 = RunTest(x => (x.BO1.I1 == null || x.BO1.I1 != 1) && (x.BO2.J1 == null || x.BO2.J1 != 1), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + int r2 = RunTest(x => !!((x.BO1.I1 == null || x.BO1.I1 != 1) && (x.BO2.J1 == null || x.BO2.J1 != 1)), + Setters<TBO1_I, TBO2_J>(MyBO.SetBO1_I1, MyBO.SetBO2_J1)); + Assert.Greater(r1, 0); + Assert.AreEqual(r1, r2); + } + } +} Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj =================================================================== --- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-25 05:55:52 UTC (rev 5757) +++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test.csproj 2011-04-25 05:57:46 UTC (rev 5758) @@ -778,6 +778,7 @@ <Compile Include="NHSpecificTest\NH2583\AbstractMassTestingFixture.cs" /> <Compile Include="NHSpecificTest\NH2583\Domain.cs" /> <Compile Include="NHSpecificTest\NH2583\ManualTestFixture.cs" /> + <Compile Include="NHSpecificTest\NH2583\MassTestingMoreOperatorsFixture.cs" /> <Compile Include="NHSpecificTest\NH2583\MassTestingNotAndDeMorganFixture.cs" /> <Compile Include="NHSpecificTest\NH2583\MassTestingOneOrTreeFixture.cs" /> <Compile Include="NHSpecificTest\NH2583\MassTestingOrderByFixture.cs" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |