context: /* This file is part of the db4o object database http://www.db4o.com
  
  Copyright (C) 2004 - 2011  Versant Corporation http://www.versant.com
  
  db4o is free software; you can redistribute it and/or modify it under
  the terms of version 3 of the GNU General Public License as published
  by the Free Software Foundation.
  
  db4o is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
  
  You should have received a copy of the GNU General Public License along
  with this program.  If not, see http://www.gnu.org/licenses/. */
  
  using System;
  using System.Collections;
  using System.Collections.Generic;
  using Db4objects.Db4o.Query;
  using Db4oUnit;
  using Db4oUnit.Extensions;
  
  namespace Db4objects.Db4o.Tests.CLI1.NativeQueries.Cats
  {
      public class TestCatConsistency : AbstractDb4oTestCase
      {
          protected override void Store()
          {
              StoreCats();
          }
  
          public void Test()
          {
              try
              {
                  Db().Configure().OptimizeNativeQueries(true);
                  RunTests();
                  Db().Configure().OptimizeNativeQueries(false);
                  RunTests();
              }
              finally
              {
                  Db().Configure().OptimizeNativeQueries(true);
              }
          }
  
          public void RunTests()
          {
  //			FIXME: COR-1535
  //			Expect(new EitherParentByName("Occam"), "Vahin\u00E9", "Achat", "Acrobat");
  
              Expect(new NoneFound());
              Expect(new AgeOne(), "Occam", "Vahin\u00E9");
              Expect(new FatherAgeOne(), "Achat", "Acrobat", "Vahin\u00E9");
              Expect(new GrandFatherName(), "Achat", "Acrobat", "Vahin\u00E9");
              Expect(new OrFatherName(), "Achat", "Acrobat", "Occam", "Vahin\u00E9");
              Expect(new AddToAge(), "Occam", "Vahin\u00E9");
              Expect(new TwoGetters(), "Occam");
              Expect(new CalculatedGetter(), "Achat");
              Expect(new GetterNull());
              Expect(new StartsWith(), "Achat", "Acrobat");
  
  #if !CF
  
              Expect(delegate(Cat cat) { return cat._age == 7; });
              Expect(delegate(Cat cat) { return cat._age == 1; }, "Occam", "Vahin\u00E9");
              Expect(delegate(Cat cat) { return cat._father._age == 1; }, "Achat", "Acrobat", "Vahin\u00E9");
              Expect(delegate(Cat cat) { return cat._father._father._firstName == "Edwin"; }, "Achat", "Acrobat",
                  "Vahin\u00E9");
              Expect(delegate(Cat cat)
              {
                  return (cat._father._father != null &&
                          cat._father._father._firstName == "Edwin")
                         || cat._father._firstName == "Edwin";
              }, "Achat", "Acrobat", "Occam", "Vahin\u00E9");
              Expect(delegate(Cat cat) { return cat._age + 1 == 2; }, "Occam", "Vahin\u00E9");
              Expect(delegate(Cat cat)
              {
                  return cat.GetFirstName() == "Occam"
                         && cat.GetAge() == 1;
              }, "Occam");
              Expect(delegate(Cat cat) { return cat.GetFullName() == "Achat Leo Lenis"; }, "Achat");
              Expect(delegate(Cat cat) { return cat.GetFullName() == null; });
              Expect(delegate(Cat cat) { return cat._firstName.StartsWith("A"); }, "Achat", "Acrobat");
  #endif
          }
  
          public void StoreCats()
          {
              var winni = new Cat();
              winni._sex = Animal.MALE;
              winni._firstName = "Edwin";
              winni._lastName = "Sanddrops";
              winni._age = 12;
  
              var bachi = new Cat();
              bachi._sex = Animal.FEMALE;
              bachi._firstName = "Frau Bachmann";
              bachi._lastName = "von der B\u00E4renh\u00F6hle";
              bachi._age = 10;
  
              var occam = new Cat();
              occam._sex = Animal.MALE;
              occam._firstName = "Occam";
              occam._lastName = "von der B\u00E4renh\u00F6hle";
              occam._age = 1;
              occam._father = winni;
              occam._mother = bachi;
  
              var zora = new Cat();
              zora._sex = Animal.FEMALE;
              zora._firstName = "Vahin\u00E9";
              zora._lastName = "des Fauves et Or";
              zora._father = occam;
              zora._age = 1;
  
              var achat = new Cat();
              achat._sex = Animal.FEMALE;
              achat._firstName = "Achat";
              achat._lastName = "Leo Lenis";
              achat._father = occam;
              achat._mother = zora;
  
              var acrobat = new Cat();
              acrobat._sex = Animal.FEMALE;
              acrobat._firstName = "Acrobat";
              acrobat._lastName = "Leo Lenis";
              acrobat._father = occam;
              acrobat._mother = zora;
  
              Store(achat);
              Store(acrobat);
  
              var trulla = new Cat();
              trulla._firstName = "Trulla";
              Store(trulla);
          }
  
          private void Expect(Predicate predicate, params string[] names)
          {
              Expect(Db().Query(predicate), names);
          }
  
          private static void Expect(IList list, string[] names)
          {
              names = names ?? new string[0];
  
              Iterator4Assert.SameContent(names, CatNamesFrom(list).GetEnumerator());
          }
  
          private static IEnumerable<string> CatNamesFrom(IList list)
          {
              foreach (Cat cat in list)
              {
                  yield return cat._firstName;
              }
          }
  
          // FIXME: COR-1535
          public class EitherParentByName : Predicate
          {
              private readonly string _parentName;
  
              public EitherParentByName(string parentName)
              {
                  _parentName = parentName;
              }
  
              public bool Match(Cat cat)
              {
                  // if the _mother field is null
                  // the right hand side of the or is
                  // never evaluated in unoptimized mode
                  return cat._mother._firstName == _parentName
                         || cat._father._firstName == _parentName;
              }
          }
  
          public class NoneFound : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._age == 7;
              }
          }
  
          public class AgeOne : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._age == 1;
              }
          }
  
          public class FatherAgeOne : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._father._age == 1;
              }
          }
  
          public class GrandFatherName : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._father._father._firstName == "Edwin";
              }
          }
  
          public class OrFatherName : Predicate
          {
              public bool Match(Cat cat)
              {
                  return (cat._father._father != null && cat._father._father._firstName == "Edwin")
                         || cat._father._firstName == "Edwin";
              }
          }
  
          public class AddToAge : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._age + 1 == 2;
              }
          }
  
          public class TwoGetters : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat.GetFirstName() == "Occam"
                         && cat.GetAge() == 1;
              }
          }
  
          public class CalculatedGetter : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat.GetFullName() == "Achat Leo Lenis";
              }
          }
  
          public class GetterNull : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat.GetFullName() == null;
              }
          }
  
          public class StartsWith : Predicate
          {
              public bool Match(Cat cat)
              {
                  return cat._firstName.StartsWith("A");
              }
          }
  
  #if !CF
          private void Expect<Extent>(Predicate<Extent> match, params string[] names)
          {
  
gt:             var list = Db().Query(match);