public void SetValues_when_nested_dictionary_in_target_is_null_throws()
        {
            var nestedValues = new TestInternalPropertyValues<FakeTypeWithProps>();

            var fromProperties = new Dictionary<string, object>
                                     {
                                         { "NestedObject", nestedValues }
                                     };
            var fromValues = new TestInternalPropertyValues<FakeTypeWithProps>(fromProperties, new[] { "NestedObject" });

            var toProperties = new Dictionary<string, object>
                                   {
                                       { "NestedObject", null }
                                   };
            var toValues = new TestInternalPropertyValues<FakeTypeWithProps>(toProperties, new[] { "NestedObject" });

            Assert.Equal(
                Strings.DbPropertyValues_NestedPropertyValuesNull("NestedObject", typeof(FakeTypeWithProps).Name),
                Assert.Throws<InvalidOperationException>(() => toValues.SetValues(fromValues)).Message);
        }
        public void SetValues_does_not_attempt_to_set_values_that_are_not_different()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "PublicStringProp", "PublicStringPropValue" },
                                     { "PublicIntProp", 2 },
                                     { "PublicBinaryProp", new byte[] { 3, 1, 4, 1, 5, 9 } },
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            var obj = new FakeTypeWithProps
                          {
                              PublicStringProp = "PublicStringPropValue",
                              PublicIntProp = 2,
                              PublicBinaryProp = new byte[] { 3, 1, 4, 1, 5, 9 }
                          };

            values.SetValues(obj);

            values.GetMockItem("PublicStringProp").VerifySet(i => i.Value = It.IsAny<object>(), Times.Never());
            values.GetMockItem("PublicIntProp").VerifySet(i => i.Value = It.IsAny<object>(), Times.Never());
            values.GetMockItem("PublicBinaryProp").VerifySet(i => i.Value = It.IsAny<object>(), Times.Never());
        }
        public void Attempt_to_copy_values_from_dictionary_of_wrong_type_throws()
        {
            var values1 = new TestInternalPropertyValues<FakeDerivedTypeWithProps>();
            var values2 = new TestInternalPropertyValues<FakeTypeWithProps>();

            Assert.Equal(
                Strings.DbPropertyValues_AttemptToSetValuesFromWrongType(
                    typeof(FakeTypeWithProps).Name, typeof(FakeDerivedTypeWithProps).Name),
                Assert.Throws<ArgumentException>(() => values1.SetValues(values2)).Message);
        }
        public void SetValues_when_complex_object_is_null_throws()
        {
            var nestedProperties = new Dictionary<string, object>
                                       {
                                           { "Id", 0 }
                                       };
            var nestedValues = new TestInternalPropertyValues<FakeTypeWithProps>(nestedProperties);

            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "NestedObject", nestedValues }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties, new[] { "NestedObject" });

            var obj = new FakeTypeWithProps
                          {
                              Id = 1,
                              NestedObject = null
                          };

            Assert.Equal(
                Strings.DbPropertyValues_ComplexObjectCannotBeNull("NestedObject", typeof(FakeTypeWithProps).Name),
                Assert.Throws<InvalidOperationException>(() => values.SetValues(obj)).Message);
        }
        public void SetValues_when_nested_property_dictionary_in_source_is_null_throws()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "NestedObject", null }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties, new[] { "NestedObject" });

            var obj = new FakeTypeWithProps
                          {
                              Id = 1,
                              NestedObject = new FakeTypeWithProps
                                                 {
                                                     Id = 2
                                                 }
                          };

            Assert.Equal(
                Strings.DbPropertyValues_NestedPropertyValuesNull("NestedObject", typeof(FakeTypeWithProps).Name),
                Assert.Throws<InvalidOperationException>(() => values.SetValues(obj)).Message);
        }
        public void SetValues_can_set_reference_propeties_to_null()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "PublicStringProp", "NonNull" }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            values.SetValues(
                new FakeTypeWithProps
                    {
                        Id = 1
                    });

            Assert.Equal(1, values["Id"]);
            Assert.Null(values["PublicStringProp"]);
        }
        public void SetValues_sets_values_from_complex_object_into_nested_property_dictionary()
        {
            var nestedProperties = new Dictionary<string, object>
                                       {
                                           { "Id", 0 }
                                       };
            var nestedValues = new TestInternalPropertyValues<FakeTypeWithProps>(nestedProperties);

            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "NestedObject", nestedValues }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties, new[] { "NestedObject" });

            values.SetValues(
                new FakeTypeWithProps
                    {
                        Id = 1,
                        NestedObject = new FakeTypeWithProps
                                           {
                                               Id = 2
                                           }
                    });

            Assert.Equal(1, values["Id"]);
            Assert.Equal(2, nestedValues["Id"]);
        }
        public void SetValues_ignores_properties_that_are_write_only()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "PublicWriteOnlyStringProp", "Foo" },
                                     { "PrivateWriteOnlyStringProp", "Bar" }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            values.SetValues(
                new FakeTypeWithProps
                    {
                        Id = 1
                    });

            Assert.Equal(1, values["Id"]);
            Assert.Equal("Foo", values["PublicWriteOnlyStringProp"]);
            Assert.Equal("Bar", values["PrivateWriteOnlyStringProp"]);
        }
        public void SetValues_ignores_properties_that_are_conceptually_in_shadow_state()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "MissingProp", "MissingPropValue" }
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            values.SetValues(
                new FakeTypeWithProps
                    {
                        Id = 1
                    });

            Assert.Equal(1, values["Id"]);
            Assert.Equal("MissingPropValue", values["MissingProp"]);
        }
        private void Attempt_to_copy_values_from_object_of_differnt_type_copies_only_properties_that_match_implementation(object obj)
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "PublicStringProp", null },
                                     { "PrivateStringProp", null },
                                     { "PublicIntProp", 0 },
                                     { "PrivateIntProp", 0 },
                                     { "PublicIntPropWithPrivateSetter", 0 },
                                     { "PublicIntPropWithPrivateGetter", 0 },
                                     { "PublicBinaryProp", null },
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            values.SetValues(obj);

            Assert.Equal(0, values["Id"]);
            Assert.Equal("PublicStringPropValue", values["PublicStringProp"]);
            Assert.Equal(0, values["PublicIntProp"]);
            Assert.Null(values["PrivateStringProp"]);
            Assert.Equal(3, values["PrivateIntProp"]);
            Assert.Equal(0, values["PublicIntPropWithPrivateSetter"]);
            Assert.Equal(0, values["PublicIntPropWithPrivateGetter"]);
            Assert.Null(values["PublicBinaryProp"]);
        }
        public void Attempt_to_copy_values_from_object_of_differnt_type_copies_no_properties_if_no_properties_match()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "PublicStringProp", null },
                                     { "PrivateStringProp", null },
                                     { "PublicIntProp", 0 },
                                     { "PrivateIntProp", 0 },
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            values.SetValues("Bang!");

            Assert.Null(values["PublicStringProp"]);
            Assert.Equal(0, values["PublicIntProp"]);
            Assert.Null(values["PrivateStringProp"]);
            Assert.Equal(0, values["PrivateIntProp"]);
        }
        public void SetValues_copies_values_from_object_to_property_dictionary()
        {
            var properties = new Dictionary<string, object>
                                 {
                                     { "Id", 0 },
                                     { "PublicStringProp", null },
                                     { "PrivateStringProp", null },
                                     { "PublicIntProp", 0 },
                                     { "PrivateIntProp", 0 },
                                     { "PublicIntPropWithPrivateSetter", 0 },
                                     { "PublicIntPropWithPrivateGetter", 0 },
                                     { "PublicBinaryProp", null },
                                 };
            var values = new TestInternalPropertyValues<FakeTypeWithProps>(properties);

            var obj = new FakeTypeWithProps(
                1, "PublicStringPropValue", "PrivateStringPropValue", 2, 3, 4, 5, new byte[] { 3, 1, 4, 1, 5, 9 });

            values.SetValues(obj);

            Assert.Equal(1, values["Id"]);
            Assert.Equal("PublicStringPropValue", values["PublicStringProp"]);
            Assert.Equal(2, values["PublicIntProp"]);
            Assert.Equal("PrivateStringPropValue", values["PrivateStringProp"]);
            Assert.Equal(3, values["PrivateIntProp"]);
            Assert.Equal(4, values["PublicIntPropWithPrivateSetter"]);
            Assert.Equal(5, values["PublicIntPropWithPrivateGetter"]);
            Assert.True(DbHelpers.KeyValuesEqual(new byte[] { 3, 1, 4, 1, 5, 9 }, values["PublicBinaryProp"]));
        }