public void ReturnsEmptyListOfTPropertyTypeByDefault()
 {
     var expected = new List<int>();
     var sieve = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt);
     
     sieve.AcceptableValues.Should().NotBeNull();
     sieve.AcceptableValues.ShouldBeEquivalentTo(expected);
 }
            public void DoesntCountNullValues()
            {

                var sut = new EqualitySieve<ABusinessObject>()
                    .ForProperty(x => x.AString)
                    .ForValue(null)
                    .ForAdditionalValue(null);
                sut.AcceptableValues.Should().BeEmpty();
            }
            public void DeclaringASieveForSubTypeAndPassingBusinessObject_Works()
            {
                var businessObj1 = new ABusinessObject { AComplexProperty =new ComplexProperty { AnInt = 1, AString = "Hello" }};
                var businessObj2 = new ABusinessObject { AComplexProperty = new ComplexProperty { AnInt = 2, AString = "Hello" } };

                var sieve = new EqualitySieve<ComplexProperty>().ForProperty(x => x.AnInt).ForValue(1).ToCompiledExpression();

                sieve.Invoke(businessObj1.AComplexProperty).Should().BeTrue();
                sieve.Invoke(businessObj2.AComplexProperty).Should().BeFalse();
            }
                public void WhenValueExists_AddsAdditionalValue()
                {
                    var expectedValues = new List<int> { 1 };
                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForAdditionalValue("1");

                    sut.AcceptableValues.Should().BeEquivalentTo(expectedValues);
                }
                public void PlaysNicelyWithForValues_TPropertyEnumerable()
                {
                    var expected = new List<int> { 1, 2,3 };

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValues(new[]{1,2})
                            .ForAdditionalValue("3");

                    sut.AcceptableValues.ShouldBeEquivalentTo(expected);
                }
            public void WithoutCalling_InvalidValueBehaviorIsSetByDefaultToIgnore()
            {
                var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.ADateTime);

                sut.InvalidValueBehavior.ShouldBeEquivalentTo(InvalidValueBehavior.IgnoreInvalidValue);

            }
                public void ListOfStrings_BecomesListOfAcceptableStringValues()
                {
                    var valuesToTry = new[] { "One", "Three" };

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AString).ForValues(valuesToTry);
                    sut.AcceptableValues.Should().BeEquivalentTo(valuesToTry);

                    var compiled = sut.ToCompiledExpression();

                    compiled.Invoke(ABusinessObjectWithAStringOfOne).Should().BeTrue();
                    compiled.Invoke(ABusinessObjectWithAStringOfTwo).Should().BeFalse();
                    compiled.Invoke(ABusinessObjectWithAStringOfThree).Should().BeTrue();

                }
                public void ArrayOfInts_BecomesListOfAcceptableValues()
                {
                    var valuesToTry = new[] { 1, 3 };

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValues(valuesToTry);
                    sut.AcceptableValues.Should().BeEquivalentTo(valuesToTry);
                }
                public void ClearsOtherPotentialValues()
                {
                    var expected = new List<int> { 5, 6 };
                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValues(new[] { 2, 3, 4 })
                            .ForValue(1)
                            .ForValues(new[] { 5, 6 });

                    sut.AcceptableValues.ShouldBeEquivalentTo(expected);
                }
                WhenSpecifyingAnExceptionBeThrown_InvalidValueThrowsInvalidSieveValueExceptionWhenCallingToExpression
                ()
            {
                const string STRING_VALUES = "7/25/2010, 12/1abc/2012";

                var sieve =
                    new EqualitySieve<ABusinessObject>().ForProperty(x => x.ADateTime)
                        .WithInvalidValueBehavior(InvalidValueBehavior.ThrowInvalidSieveValueException)
                        .ForValue(STRING_VALUES);

                // ReSharper disable once UnusedVariable -- used for purposes of this action only
                Action act = () => { var sut = sieve.ToExpression(); };

                act.ShouldThrow<InvalidSieveValueException>()
                    .And.Message.Should()
                    .ContainEquivalentOf("12/1abc/2012");
            }
            public void WithoutPropertySet_ThrowsSievePropertyNotSetException()
            {
                var sieve = new EqualitySieve<ABusinessObject, int>().ForValue(1);

                Action act = () => sieve.ToExpression();

                act.ShouldThrow<SievePropertyNotSetException>()
                    .And.Message.Should()
                    .ContainEquivalentOf("try calling ForProperty");
            }
                public void SingleString_WhenPropertyIsString_AddsToList()
                {
                    const string STRING_TO_TEST = "Hello World";

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AString).ForValue(STRING_TO_TEST);

                    var expectedList = new List<string> { STRING_TO_TEST };
                    sut.AcceptableValues.Should().BeEquivalentTo(expectedList);
                }
                    WithInvalidValue_AndInvalidValueBehaviorSetToThrowException_ExceptionIsThrownWhenToExpressionIsCalled
                    ()
                {
                    var sieve =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .WithInvalidValueBehavior(InvalidValueBehavior.ThrowInvalidSieveValueException)
                            .ForValue("2abc");

                    // ReSharper disable once UnusedVariable -- used for purposes of this action only
                    Action act = () => { var sut = sieve.ToExpression(); };

                    act.ShouldThrow<InvalidSieveValueException>().And.Message.Should().ContainEquivalentOf("2abc");

                }
                public void WithInvalidValue_IgnoredByDefault()
                {
                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue("2abc");

                    sut.AcceptableValues.Should().BeEmpty();
                }
                public void CanBeCalledAgainToReplaceValueAfterFirstCausesAnError()
                {
                    const int ACCEPTABLE_VALUE = 1;
                    string acceptableValueInStringform = ACCEPTABLE_VALUE.ToString(CultureInfo.InvariantCulture);

                    const string UNACCEPTABLE_VALUE = "1abc";
                    var expectedFinalList = new List<int> { ACCEPTABLE_VALUE };

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .WithInvalidValueBehavior(InvalidValueBehavior.ThrowInvalidSieveValueException)
                            .ForValue(UNACCEPTABLE_VALUE);

                    // ReSharper disable once UnusedVariable -- used in deferred action
                    Action act = () => { var values = sut.AcceptableValues; };

                    act.ShouldThrow<InvalidSieveValueException>()
                        .And.Message.Should()
                        .ContainEquivalentOf(UNACCEPTABLE_VALUE);

                    sut.ForValue(acceptableValueInStringform);

                    sut.AcceptableValues.Should().BeEquivalentTo(expectedFinalList);
                }
            public void ForValue_MattersWhenToExpressionIsCalled()
            {
                ISieve<ABusinessObject, int> sieve = null;

                Action actCreateSieve = () =>
                {
                    sieve =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValue("1abc")
                            .WithInvalidValueBehavior(InvalidValueBehavior.ThrowInvalidSieveValueException);
                };

                actCreateSieve.Invoke();

                Action actGetAcceptableValues = () =>
                {
                    Debug.Assert(sieve != null, "sieve != null");
                    // ReSharper disable once UnusedVariable -- used for purposes of this action only
                    var sut = sieve.ToExpression();
                };

                actCreateSieve.ShouldNotThrow<InvalidSieveValueException>();
                actGetAcceptableValues.ShouldThrow<InvalidSieveValueException>()
                    .And.Message.Should()
                    .ContainEquivalentOf("1abc");

            }
                public void ForProperty_WithExpression_SetsProperty()
                {
                    const string PROPERTY_NAME = "AnInt";
                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt);

                    sut.PropertyToFilter.Name.Should().Be(PROPERTY_NAME);

                }
                public void DoesNotAddDuplicateValues()
                {
                    var expected = new List<int> { 1, 2, 3 };

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForAdditionalValues(new[] { "1", "1", "1", "2", "1", "3", "1" });

                    sut.AcceptableValues.ShouldBeEquivalentTo(expected);
                }
                public void WhenNoValueListsExist_AddsValues()
                {
                    var listOfValues = new List<int> { 1, 2, 3 };
                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForAdditionalValues("1, 2, 3");

                    sut.AcceptableValues.Should().BeEquivalentTo(listOfValues);
                }
            public void WhenSpecifyingItShouldbeIgnored_InvalidValuesAreIgnoredByDefault()
            {
                const string STRING_VALUES = "7/25/2010, 12/1abc/2012";

                var expectedList = new List<DateTime> { new DateTime(2010, 7, 25) };

                var sut =
                    new EqualitySieve<ABusinessObject>().ForProperty(x => x.ADateTime)
                        .WithInvalidValueBehavior(InvalidValueBehavior.IgnoreInvalidValue)
                        .ForValues(STRING_VALUES);

                sut.InvalidValueBehavior.ShouldBeEquivalentTo(InvalidValueBehavior.IgnoreInvalidValue);
                sut.AcceptableValues.ShouldBeEquivalentTo(expectedList);
            }
                public void PlaysNicelyWithForValues_String()
                {
                    var expected = new List<int> { 1, 2, 3,4 };

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValues("1, 2")
                            .ForAdditionalValues("3, 4");

                    sut.AcceptableValues.ShouldBeEquivalentTo(expected);
                }
                public void SingleString_WhenPropertyIsNotAString_ConvertsAndAddsToList()
                {
                    const string STRING_TO_TEST = "123";

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue(STRING_TO_TEST);

                    var expectedList = new List<int> { 123 };
                    sut.AcceptableValues.Should().BeEquivalentTo(expectedList);

                }
                public void WhenValueListExists_AddsAdditionalValueList()
                {
                    var listOfValues = new List<int> { 1, 2, 3 };
                    var additionalValues = new List<int> { 4, 5, 6 };

                    var fullList = listOfValues.ToList().Union(additionalValues);

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValues("1, 2, 3")
                            .ForAdditionalValues("4, 5, 6");

                    sut.AcceptableValues.Should().BeEquivalentTo(fullList);

                }
                public void SingleString_WhenInvalidToConvert_SetsAcceptableValuesToEmptyList()
                {
                    const string STRING_TO_TEST = "123abc";

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue(STRING_TO_TEST);

                    var expectedList = new List<int>();
                    sut.AcceptableValues.Should().BeEquivalentTo(expectedList);
                }
                public void ListOfInts_BecomesListOfAcceptableValues()
                {
                    var valuesToTry = new List<int> { 1, 3 };

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValues(valuesToTry);
                    sut.AcceptableValues.Should().BeEquivalentTo(valuesToTry);

                    var compiled = sut.ToCompiledExpression();
                    compiled.Invoke(ABusinessObjectWithAnIntOf1).Should().BeTrue();
                    compiled.Invoke(ABusinessObjectWithAnIntOf2).Should().BeFalse();
                    compiled.Invoke(ABusinessObjectWithAnIntOf3).Should().BeTrue();
                }
                public void WhenCalled_ReplacesPreviousItems()
                {
                    var expectedValuesFirstTime = new List<int> { 1 };
                    var expectedValuesSecondTime = new List<int> { 2 };

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue(1);

                    sut.AcceptableValues.Should().BeEquivalentTo(expectedValuesFirstTime);

                    sut.ForValue(2);

                    sut.AcceptableValues.Should().BeEquivalentTo(expectedValuesSecondTime);

                }
            public void SingleValue_MatchesOnlyThatValue()
            {
                var sieve = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue(1);

                var sut = sieve.ToExpression();

                sut.Compile().Invoke(ABusinessObjectWithAnIntOf1).Should().BeTrue();
                sut.Compile().Invoke(ABusinessObjectWithAnIntOf2).Should().BeFalse();
                sut.Compile().Invoke(ABusinessObjectWithAnIntOf3).Should().BeFalse();
            }
                public void SingleItemOfPropertyType_SetsAcceptableValuesList()
                {
                    const int NUMBER_TO_TEST = 123;

                    var sut = new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt).ForValue(NUMBER_TO_TEST);

                    var expectedList = new List<int> { NUMBER_TO_TEST };
                    sut.AcceptableValues.Should().BeEquivalentTo(expectedList);
                }
                public void DoesNotAddDuplicateValues()
                {
                    var expected = new List<int> { 1, 2, 3 };

                    var sut =
                        new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                            .ForValues("1, 1, 1, 2, 1, 3, 1");

                    sut.AcceptableValues.ShouldBeEquivalentTo(expected);
                }
            public void WithLetNoneThroughOption_DoesNotAllowAnyThrough()
            {
                //no values defined
                var sut =
                    new EqualitySieve<ABusinessObject>().ForProperty(x => x.AnInt)
                        .WithEmptyValuesListBehavior(EmptyValuesListBehavior.LetNoObjectsThrough)
                        .ToCompiledExpression();

                sut.Invoke(ABusinessObjectWithAnIntOf1).Should().BeFalse();
                sut.Invoke(ABusinessObjectWithAnIntOf2).Should().BeFalse();
                sut.Invoke(ABusinessObjectWithAnIntOf3).Should().BeFalse();
            }