public void Get_With_String_Selector_Should_Return_Item_If_Item_Exists(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User" };
            repository.Add(contact);

            var result = repository.Get(contact.ContactId, c => c.Name);
            result.ShouldEqual("Test User");
        }
        public void Get_Should_Return_Item_If_Item_Exists(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User", ContactTypeId = 1 };
            repository.Add(contact);

            var result = repository.Get(contact.ContactId);
            result.Name.ShouldEqual(contact.Name);
            result.ContactTypeId.ShouldEqual(contact.ContactTypeId);
        }
        public void Get_With_Anonymous_Class_Selector_Should_Return_Item_If_Item_Exists(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User", ContactTypeId = 2 };
            repository.Add(contact);

            var result = repository.Get(contact.ContactId, c => new { c.ContactTypeId, c.Name });
            result.ContactTypeId.ShouldEqual(2);
            result.Name.ShouldEqual("Test User");
        }
        public void Average_All_Should_Return_Average(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =i};
                repository.Add(contact);
            }

            repository.Average(x => x.ContactTypeId).ShouldEqual(2.0);
        }
        public void Average_With_Specification_Should_Return_Average(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =i};
                repository.Add(contact);
            }

            repository.Average(new Specification<Contact>(x => x.ContactTypeId > 1), x => x.ContactTypeId).ShouldEqual(2.5);
        }
        public void Average_Decimal_With_Predicate_Should_Return_Average(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = i, SumDecimal = 0.5m + i };
                repository.Add(contact);
            }

            repository.Average(x => x.ContactTypeId > 1, x => x.SumDecimal).ShouldEqual(3m);
        }
        public void FindAll_Should_Return_All_Items_Which_Satisfy_Composite_Specification(IRepository<Contact, string> repository)
        {
            for (int i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            var result = repository.FindAll(new Specification<Contact>(p => p.Name == "Test User 1").OrElse(new Specification<Contact>(p => p.Name == "Test User 2")));
            result.Count().ShouldEqual(2);
        }
        public void GetAll_With_Selector_Should_Return_Every_Item(IRepository<Contact, string> repository)
        {
            for (int i = 1; i <= 5; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            var result = repository.GetAll(c => c.Name);
            result.Count().ShouldEqual(5);
        }
        public void GetMany_Params_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 5; i++)
            {
                var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
                repository.Add(contact);
            }

            var items = repository.GetMany("1", "3", "4", "5");
            items.Count().ShouldEqual(4);
        }
        public void GetAll_Should_Return_Every_Item(IRepository<Contact, string> repository)
        {
            for (int i = 1; i <= 5; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            IEnumerable<Contact> result = repository.GetAll().ToList();
            result.Count().ShouldEqual(5);
        }
        public void Delete_Should_Remove_Item_By_Key(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User" };
            repository.Add(contact);

            var result = repository.Get(contact.ContactId);
            result.ShouldNotBeNull();

            repository.Delete(contact.ContactId);
            result = repository.Get(contact.ContactId);
            result.ShouldBeNull();
        }
        public void Find_Should_Return_First_Ordered_Item_Which_Satisfies_Specification_WIth_Sorting_Predicate(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            var result = repository.Find(new Specification<Contact>(p => p.Name.StartsWith("Test")), new SortingOptions<Contact, string>(c => c.Name, true));
            result.Name.ShouldEqual("Test User 3");

            var result2 = repository.Find(new Specification<Contact>(p => p.Name.StartsWith("Test")), new SortingOptions<Contact, string>(c => c.Name, false));
            result2.Name.ShouldEqual("Test User 1");
        }
        public void GetManyAsDictionary_List_Should_Return_Multiple_Items(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 5; i++)
            {
                var contact = new Contact { ContactId = i.ToString(), Name = "Test User " + i};
                repository.Add(contact);
            }

            var items = repository.GetManyAsDictionary(new [] {"1", "3", "4", "5" }.ToList());
            items.ContainsKey("1").ShouldBeTrue();
            items.ContainsKey("2").ShouldBeFalse();
            items.ContainsKey("3").ShouldBeTrue();
            items.ContainsKey("4").ShouldBeTrue();
            items.ContainsKey("5").ShouldBeTrue();
        }
        public void Count_Should_Return_All_Count(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =1};
                repository.Add(contact);
            }
            for (var i = 4; i <= 7; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = 2};
                repository.Add(contact);
            }

            repository.Count().ShouldEqual(7);
        }
        public void Update_Should_Save_Modified_Business_Name(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User" };
            repository.Add(contact);

            var contact2 = new Contact { Name = "Test User 2" };
            repository.Add(contact2);

            contact.Name = "Test User - Updated";
            repository.Update(contact);

            var updated = repository.Get(contact.ContactId);
            var notUpdated = repository.Get(contact2.ContactId);

            updated.Name.ShouldEqual("Test User - Updated");
            notUpdated.Name.ShouldEqual("Test User 2");
        }
        public void GetAll_Should_Return_Every_Items_With_Paging(IRepository<Contact, string> repository)
        {
            const int resultingPage = 2;
            const int pageSize = 2;
            const int totalItems = 5;

            var queryOptions = new PagingOptions<Contact>(resultingPage, pageSize, "Name");

            for (int i = 1; i <= totalItems; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            IEnumerable<Contact> result = repository.GetAll(queryOptions).ToList();
            result.Count().ShouldEqual(pageSize);
            queryOptions.TotalItems.ShouldEqual(totalItems);
            result.First().Name.ShouldEqual("Test User 3");
        }
        public void GetAll_With_Anonymous_Selector_Should_Return_Every_Item(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 5; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            var results = repository.GetAll(c => new {c.Name, c.Title});

            var total = 0;
            foreach (var result in results)
            {
                result.Name.ShouldStartWith("Test User");
                total++;
            }

            total.ShouldEqual(5);
        }
        public void Delete_By_Params_Should_Remove_Multiple_Items(IRepository<Contact, string> repository)
        {
            var contact1 = new Contact {Name = "Contact 1", ContactTypeId = 1};
            var contact2 = new Contact {Name = "Contact 2", ContactTypeId = 1};
            var contact3 = new Contact {Name = "Contact 3", ContactTypeId = 3};

            repository.Add(contact1);
            repository.Add(contact2);
            repository.Add(contact3);

            var items = repository.GetAll().ToList();
            items.Count().ShouldEqual(3);

            repository.Delete(contact1.ContactId, contact2.ContactId);

            items = repository.GetAll().ToList();
            items.Count().ShouldEqual(1);
            items.First().Name.ShouldEqual("Contact 3");
        }
        public void Delete_Should_Wait_To_Remove_Item_If_Item_Exists_In_BatchMode(IRepository<Contact, string> repository)
        {
            var contact = new Contact { Name = "Test User" };
            repository.Add(contact);

            var result = repository.Get(contact.ContactId);
            result.ShouldNotBeNull();

            using (var batch = repository.BeginBatch())
            {
                batch.Delete(contact); // not really delete until call Save, because in BatchMode

                result = repository.Get(contact.ContactId);
                result.ShouldNotBeNull();

                batch.Commit(); // actually do the delete
            }

            result = repository.Get(contact.ContactId);
            result.ShouldBeNull();
        }
        public void FindAll_Should_Return_All_Items_Which_Satisfy_Composite_Specification_With_Paging_And_Sort_Descending(IRepository<Contact, string> repository)
        {
            const int resultingPage = 2;
            const int pageSize = 2;
            var queryOptions = new PagingOptions<Contact>(resultingPage, pageSize, "Name", true);

            for (int i = 1; i <= 10; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            IEnumerable<Contact> result = repository
                .FindAll(new Specification<Contact>(p => p.Name == "Test User 1")
                                .OrElse(new Specification<Contact>(p => p.Name == "Test User 5")
                                        .OrElse(new Specification<Contact>(p => p.Name == "Test User 8"))),
                            queryOptions);

            result.Count().ShouldEqual(1);
            queryOptions.TotalItems.ShouldEqual(3);
            result.First().Name.ShouldEqual("Test User 1");
        }
        public void Join_GetAll_Should_Return_All_Items(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 5; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = (i % 2) + 1};
                repository.Add(contact);
            }

            var contactTypeRepository = new InMemoryRepository<ContactType, int>();
            contactTypeRepository.Add(new ContactType() { ContactTypeId = 1, Abbreviation = "T1"});
            contactTypeRepository.Add(new ContactType() { ContactTypeId = 2, Abbreviation = "T2" });

            var compositeRepos = repository.Join(contactTypeRepository, c => c.ContactTypeId, ct => ct.ContactTypeId,
                            (c, ct) => new { Id = c.ContactId, Name = c.Name, TypeAbbrev = ct.Abbreviation });

            var all = compositeRepos.GetAll().ToList();

            all.Count.ShouldEqual(5);

            //IEnumerable<Contact> result = repository.GetAll().ToList();
            //result.Count().ShouldEqual(5);
        }
        public void FindAll_Should_Return_All_Items_Which_Satisfy_Specification_With_Paging_MagicString(IRepository<Contact, string> repository)
        {
            const int resultingPage = 2;
            const int pageSize = 2;
            const int totalItems = 10;

            var queryOptions = new PagingOptions<Contact>(resultingPage, pageSize, "Name");

            for (int i = 1; i <= totalItems; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = i };
                repository.Add(contact);
            }

            // this fails for RavenDb because the ContactId is an int but is being used as the key, so the check on ContactId <= 5 is doing a string comparison and including ContactId = 10 as well
            //  need to look into why this happens and how to get around it
            var result = repository.FindAll(new Specification<Contact>(p => p.ContactTypeId <= totalItems / 2), queryOptions);
            result.Count().ShouldEqual(pageSize);
            queryOptions.TotalItems.ShouldEqual(totalItems / 2);
            result.First().Name.ShouldEqual("Test User 3");
        }
        public void FindAll_Should_Return_All_Items_Which_Satisfy_Specification(IRepository<Contact, string> repository)
        {
            for (int i = 1; i <= 3; i++)
            {
                var contact = new Contact {Name = "Test User " + i};
                repository.Add(contact);
            }

            var result = repository.FindAll(new Specification<Contact>(p => p.Name == "Test User 1")); // Note: Raven doesn't like p.Name.Equals("...");
            result.Count().ShouldEqual(1);
        }
        public void Count_With_Predicate_Should_Return_Count(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =1};
                repository.Add(contact);
            }
            for (var i = 4; i <= 7; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = 2};
                repository.Add(contact);
            }

            repository.Count(x => x.ContactTypeId == 2).ShouldEqual(4);
        }
        public void Find_Should_Return_Single_Item_Which_Satisfies_Composite_Specification(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i };
                repository.Add(contact);
            }

            var result = repository.Find(new Specification<Contact>(p => p.Name == "Test User 1").OrElse(new Specification<Contact>(p => p.Name == "Test User 1000")));
            result.Name.ShouldEqual("Test User 1");
        }
        public void GroupLongCount_Should_Return_Proper_Counts(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =1};
                repository.Add(contact);
            }
            for (var i = 4; i <= 7; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = 2};
                repository.Add(contact);
            }

            var groups = repository.GroupLongCount(x => x.ContactTypeId);

            groups.Count().ShouldEqual(2);

            const long expected1 = 3;
            const long expected2 = 4;
            groups[1].ShouldEqual(expected1);
            groups[2].ShouldEqual(expected2);
        }
        public void Sum_With_Predicate_Should_Return_Sum(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =i};
                repository.Add(contact);
            }

            repository.Sum(x => x.ContactTypeId > 1, x => x.ContactTypeId).ShouldEqual(5);
        }
        public void Sum_Decimal_All_Should_Return_Sum(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = i, SumDecimal = 0.5m + i };
                repository.Add(contact);
            }

            repository.Sum(x => x.SumDecimal).ShouldEqual(7.5m);
        }
        public void Min_All_Should_Return_One(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = i, SumDecimal = 0.5m + i };
                repository.Add(contact);
            }

            repository.Min(x => x.ContactTypeId).ShouldEqual(1);
        }
        public void Group_Should_Return_Proper_Items(IRepository<Contact, string> repository)
        {
            for (var i = 1; i <= 3; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId =1};
                repository.Add(contact);
            }
            for (var i = 4; i <= 7; i++)
            {
                var contact = new Contact { Name = "Test User " + i, ContactTypeId = 2};
                repository.Add(contact);
            }

            var groups = repository.GroupBy(new Specification<Contact>(x => x.ContactTypeId > 0), x => x.ContactTypeId,
                                          x => new { ContactTypeId = x.Key, Count = x.Count(), Average = x.Average(o => o.ContactTypeId) });

            //var groups = repository.GroupItems(x => x.ContactTypeId, x => x.Title);
            groups.First().ContactTypeId.ShouldEqual(1);
            groups.First().Count.ShouldEqual(3);
            groups.First().Average.ShouldEqual(1.0);
            groups.Last().ContactTypeId.ShouldEqual(2);
            groups.Last().Count.ShouldEqual(4);
            groups.Last().Average.ShouldEqual(2.0);
        }