コード例 #1
0
        public void OpenTypeConverterWithOneGenericArg()
        {
            var cm = new ConverterManager();

            // Register a converter builder.
            // Builder runs once; converter runs each time.
            // Uses open type to match.
            // Also test the IEnumerable<OpenType> pattern.

            cm.AddConverter <OpenType, IEnumerable <OpenType>, Attribute>(typeof(TypeConverterWithOneGenericArg <>));

            var attr = new TestAttribute(null);
            {
                // Doesn't match since the OpenTypes would resolve to different Ts
                var converter = cm.GetSyncConverter <object, IEnumerable <int>, Attribute>();
                Assert.Null(converter);
            }
            {
                var converter = cm.GetSyncConverter <int, IEnumerable <int>, Attribute>();
                Assert.Equal(new int[] { 1, 1, 1 }, converter(1, attr, null));
            }

            {
                var converter = cm.GetSyncConverter <string, IEnumerable <string>, Attribute>();
                Assert.Equal(new string[] { "a", "a", "a" }, converter("a", attr, null));
            }
        }
コード例 #2
0
        public void AttributeOverloads()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <Wrapper, string, TestAttribute>((x, attr) => string.Format("[t1:{0}-{1}]", x.Value, attr.Flag));
            cm.AddConverter <Wrapper, string, TestAttribute2>((x, attr) => string.Format("[t2:{0}-{1}]", x.Value, attr.Flag));

            // Since converter was registered for a specific attribute, it must be queried by that attribute.
            var funcMiss = cm.GetSyncConverter <Wrapper, string, Attribute>();

            Assert.Null(funcMiss);

            // Each attribute type has its own conversion function
            var func1 = cm.GetSyncConverter <Wrapper, string, TestAttribute>();

            Assert.NotNull(func1);
            var x1 = func1(new Wrapper {
                Value = "x"
            }, new TestAttribute("y"), context);

            Assert.Equal("[t1:x-y]", x1);

            var func2 = cm.GetSyncConverter <Wrapper, string, TestAttribute2>();

            Assert.NotNull(func2);
            var x2 = func2(new Wrapper {
                Value = "x"
            }, new TestAttribute2("y"), context);

            Assert.Equal("[t2:x-y]", x2);
        }
コード例 #3
0
        public void AttributeOverloads2()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <Wrapper, string, TestAttribute>((x, attr) => string.Format("[t1:{0}-{1}]", x.Value, attr.Flag));
            cm.AddConverter <Wrapper, string>(x => string.Format("[common:{0}]", x.Value));

            // This has an exact match on attribute and gives the specific function we registered.
            var func1 = cm.GetSyncConverter <Wrapper, string, TestAttribute>();

            Assert.NotNull(func1);
            var x1 = func1(new Wrapper {
                Value = "x"
            }, new TestAttribute("y"), context);

            Assert.Equal("[t1:x-y]", x1);

            // Nothing registered for this attribute, so we return the converter that didn't require any attribute.
            var func2 = cm.GetSyncConverter <Wrapper, string, TestAttribute2>();

            Assert.NotNull(func2);
            var x2 = func2(new Wrapper {
                Value = "x"
            }, new TestAttribute2("y"), context);

            Assert.Equal("[common:x]", x2);
        }
コード例 #4
0
        public void StringAndByteArray()
        {
            var cm = new ConverterManager(); // empty

            // No default byte[]-->Wrapper conversion.
            var fromBytes = cm.GetSyncConverter <byte[], Wrapper, Attribute>();

            Assert.Null(fromBytes);

            // Add a string-->Wrapper conversion
            cm.AddConverter <string, Wrapper>(str => new Wrapper {
                Value = str
            });

            var     fromString = cm.GetSyncConverter <string, Wrapper, Attribute>();
            Wrapper obj1       = fromString("abc", null, context);

            Assert.Equal("abc", obj1.Value);

            // Now we can get a byte-->string  , composed from a default (byte[]-->string) + supplied (string-->Wrapper)
            byte[] bytes = Encoding.UTF8.GetBytes("abc");

            fromBytes = cm.GetSyncConverter <byte[], Wrapper, Attribute>();
            Assert.NotNull(fromBytes);
            Wrapper obj2 = fromBytes(bytes, null, context);

            Assert.Equal("abc", obj2.Value);

            // Now override the default. Uppercase the string so we know it used our custom converter.
            cm.AddConverter <byte[], string>(b => Encoding.UTF8.GetString(b).ToUpper());
            fromBytes = cm.GetSyncConverter <byte[], Wrapper, Attribute>();
            Wrapper obj3 = fromBytes(bytes, null, context);

            Assert.Equal("ABC", obj3.Value);
        }
コード例 #5
0
        public void OpenTypeTest()
        {
            int count = 0;
            var cm    = new ConverterManager();

            // Register a converter builder.
            // Builder runs once; converter runs each time.
            // Uses open type to match.
            cm.AddConverter <TypeWrapperIsString, int, Attribute>(
                (typeSrc, typeDest) =>
            {
                count++;
                Assert.Equal(typeof(String), typeSrc);
                Assert.Equal(typeof(int), typeDest);

                FuncAsyncConverter converter2 = (input, attr, ctx) =>
                {
                    string s = (string)input;
                    return(Task.FromResult <object>(int.Parse(s)));
                };
                return(converter2);
            });

            var converter = cm.GetSyncConverter <string, int, Attribute>();

            Assert.NotNull(converter);
            Assert.Equal(12, converter("12", new TestAttribute(null), null));
            Assert.Equal(34, converter("34", new TestAttribute(null), null));

            Assert.Equal(1, count); // converterBuilder is only called once.

            // 'char' as src parameter doesn't match the type predicate.
            Assert.Null(cm.GetSyncConverter <char, int, Attribute>());
        }
コード例 #6
0
        public void JObjectMiddleman()
        {
            var cm = new ConverterManager();

            cm.AddConverter <OpenType.Poco, JObject, Attribute>((src, dest) =>
                                                                (input, attr2, ctx) =>
            {
                var val  = JObject.FromObject(input);
                val["c"] = "custom";     // stamp an extra field to verify it's our serialization
                return(Task.FromResult <object>(val));
            });

            cm.AddConverter <JObject, Other>(obj => new Other {
                Value2 = obj["c"].ToString()
            });
            var attr = new TestAttribute(null);

            // Non poco types don't match
            Assert.Null(cm.GetSyncConverter <int, JObject, Attribute>());
            Assert.Null(cm.GetSyncConverter <Object, JObject, Attribute>());

            var converter = cm.GetSyncConverter <Wrapper, JObject, Attribute>();

            Assert.NotNull(converter);

            // Wrapper --> JObject --> Other
            var c2 = cm.GetSyncConverter <Wrapper, Other, Attribute>();

            Assert.NotNull(c2);

            Other result = c2(new Wrapper {
                Value = "x"
            }, null, null);

            Assert.Equal("custom", result.Value2);


            // If we now add a direct converter, that takes precedence
            cm.AddConverter <Wrapper, Other>(input => new Other {
                Value2 = input.Value
            });
            var direct = cm.GetSyncConverter <Wrapper, Other, Attribute>();

            Other result2 = direct(new Wrapper {
                Value = "x"
            }, null, null);

            Assert.Equal("x", result2.Value2);
        }
コード例 #7
0
        public void Replace()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <string, int>(str => int.Parse(str));

            var c = cm.GetSyncConverter <string, int, Attribute>();

            Assert.Equal(123, c("123", null, null));

            // Replace the original
            cm.AddConverter <string, int>(str => int.Parse(str) * 10);

            Assert.Equal(123, c("123", null, null)); // Original converter still works as is.
            var c2 = cm.GetSyncConverter <string, int, Attribute>();

            Assert.Equal(1230, c2("123", null, null)); // New converter pulls replaced results.
        }
コード例 #8
0
        public void UseGenericAsyncConverterTest()
        {
            var cm = new ConverterManager();

            cm.AddConverter <int, string, Attribute>(typeof(UseGenericAsyncConverter <>));

            var converter = cm.GetSyncConverter <int, string, Attribute>();

            Assert.Equal("12", converter(12, new TestAttribute(null), null));
        }
コード例 #9
0
        public void Precedence()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <OpenType, int, Attribute>((srcType, destType) =>
            {
                return((src, attr, ctx) => Task.FromResult <object>(int.Parse(src.ToString()) * 100));
            });
            cm.AddConverter <string, int>(str => int.Parse(str)); // Exact types


            var c = cm.GetSyncConverter <string, int, Attribute>();

            Assert.Equal(123, c("123", null, null)); // Exact takes precedence

            var c2 = cm.GetSyncConverter <double, int, Attribute>();

            Assert.Equal(9900, c2(99, null, null)); // Uses the open converter
        }
コード例 #10
0
        public void OpenTypeConverterWithConcreteTypes()
        {
            Assert.Equal(0, _counter);
            var cm = new ConverterManager();

            // Register a converter builder.
            // Builder runs once; converter runs each time.
            // Uses open type to match.
            cm.AddConverter <TypeWrapperIsString, int, Attribute>(typeof(TypeConverterWithConcreteTypes), this);

            var converter = cm.GetSyncConverter <string, int, Attribute>();

            Assert.Equal(12, converter("12", new TestAttribute(null), null));
            Assert.Equal(34, converter("34", new TestAttribute(null), null));

            Assert.Equal(1, _counter); // converterBuilder is only called once.

            // 'char' as src parameter doesn't match the type predicate.
            Assert.Null(cm.GetSyncConverter <char, int, Attribute>());
        }
コード例 #11
0
        public void OpenTypeSimpleConcreteConverter()
        {
            Assert.Equal(0, _counter);
            var cm = new ConverterManager();

            // Register a converter builder.
            // Builder runs once; converter runs each time.
            // Uses open type to match.
            cm.AddConverter <TypeWrapperIsString, int, Attribute>(new ConverterInstanceMethod());

            var converter = cm.GetSyncConverter <string, int, Attribute>();

            Assert.Equal(12, converter("12", new TestAttribute(null), null));
            Assert.Equal(34, converter("34", new TestAttribute(null), null));

            Assert.Equal(0, _counter); // passed in instantiated object; counter never incremented.

            // 'char' as src parameter doesn't match the type predicate.
            Assert.Null(cm.GetSyncConverter <char, int, Attribute>());
        }
コード例 #12
0
        public void ClosedTypeArray()
        {
            var cm = new ConverterManager();

            cm.AddConverter <int[], string, Attribute>(new OpenArrayConverter <int>());
            var attr = new TestAttribute(null);

            var converter = cm.GetSyncConverter <int[], string, Attribute>();

            Assert.Equal("1,2,3", converter(new int[] { 1, 2, 3 }, attr, null));
        }
コード例 #13
0
        public void Identity()
        {
            var cm = new ConverterManager(); // empty

            var identity = cm.GetSyncConverter <string, string, Attribute>();

            var value = "abc";
            var x1    = identity(value, null, context);

            Assert.Same(x1, value);
        }
コード例 #14
0
        public void Inheritence()
        {
            var cm   = new ConverterManager(); // empty
            var func = cm.GetSyncConverter <DerivedWrapper, Wrapper, Attribute>();

            var obj = new DerivedWrapper {
                Value = "x"
            };
            Wrapper x1 = func(obj, null, context);

            Assert.Same(x1, obj);
        }
コード例 #15
0
        public void ExactMatchOverride()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <string, string>(x => "*" + x + "*");

            var func = cm.GetSyncConverter <string, string, Attribute>();

            var x1 = func("x", null, context);

            Assert.Equal("*x*", x1);
        }
コード例 #16
0
        public void CatchAll()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <object, Wrapper>(x => new Wrapper {
                Value = x.ToString()
            });

            var func = cm.GetSyncConverter <int, Wrapper, Attribute>();

            var x1 = func(123, null, context);

            Assert.Equal("123", x1.Value);
        }
コード例 #17
0
        public void Converters()
        {
            ConverterManager cm = new ConverterManager();
            var ctx             = new ExtensionConfigContext(null, cm, null, null);

            // Simulates extension initialization scope.
            {
                ctx.AddBindingRule <TestAttribute>().AddConverter <int, string>(val => "specific"); // specific
                ctx.AddConverter <int, string>(val => "general");                                   // general
            }
            ctx.ApplyRules();

            {
                var generalConverter = cm.GetSyncConverter <int, string, Attribute>();
                var result           = generalConverter(12, null, null);
                Assert.Equal("general", result);
            }

            {
                var specificConverter = cm.GetSyncConverter <int, string, TestAttribute>();
                var result            = specificConverter(12, null, null);
                Assert.Equal("specific", result);
            }
        }
コード例 #18
0
        public void TestConvertFakeEntity()
        {
            var cm = new ConverterManager();

            // Derived<ITableEntity> --> IFakeEntity  [automatic]
            // JObject --> IFakeEntity
            // Poco --> IFakeEntity
            cm.AddConverter <JObject, IFakeEntity, Attribute>(typeof(TestConverterFakeEntity));
            cm.AddConverter <OpenType, IFakeEntity, Attribute>(typeof(TestConverterFakeEntity <>));

            {
                var converter = cm.GetSyncConverter <IFakeEntity, IFakeEntity, Attribute>();
                var src       = new MyFakeEntity {
                    Property = "123"
                };
                var dest = converter(src, null, null);
                Assert.Same(src, dest); // should be exact same instance - no conversion
            }

            {
                var     converter = cm.GetSyncConverter <JObject, IFakeEntity, Attribute>();
                JObject obj       = new JObject();
                obj["Property1"] = "456";
                var dest = converter(obj, null, null);
                Assert.Equal("456", dest.Property);
            }

            {
                var converter = cm.GetSyncConverter <PocoEntity, IFakeEntity, Attribute>();
                var src       = new PocoEntity {
                    Property2 = "789"
                };
                var dest = converter(src, null, null);
                Assert.Equal("789", dest.Property);
            }
        }
コード例 #19
0
        public void String2TDoesNotEnableJObject()
        {
            var cm = new ConverterManager(); // empty

            cm.AddConverter <string, Wrapper>(str => new Wrapper {
                Value = str
            });

            var objSrc = new Other {
                Value2 = "abc"
            };

            // Json Serialize: (Other --> string)
            // custom          (string -->Wrapper)
            var func = cm.GetSyncConverter <Other, Wrapper, Attribute>();

            Assert.Null(func);
        }
コード例 #20
0
        public void UseValueBindingContext()
        {
            var cm = new ConverterManager(); // empty

            Guid instance    = Guid.NewGuid();
            var  testContext = new ValueBindingContext(new FunctionBindingContext(instance, CancellationToken.None, null), CancellationToken.None);

            FuncAsyncConverter converter =
                (object obj, Attribute attr, ValueBindingContext ctx) => {
                Assert.Same(ctx, testContext);
                var result = JObject.FromObject(obj);
                result["$"] = ctx.FunctionInstanceId;
                return(Task.FromResult <object>(result));
            };

            cm.AddConverter <object, JObject, Attribute>(converter);
            cm.AddConverter <JObject, Wrapper>(str => new Wrapper {
                Value = str.ToString()
            });

            // Expected:
            //    Other --> JObject,
            //    JObject --> string ,  (builtin)
            //    string --> Wrapper
            var func = cm.GetSyncConverter <Other, Wrapper, Attribute>();

            var value = new Other {
                Value2 = "abc"
            };
            Wrapper x1 = func(value, null, testContext);
            // strip whitespace
            string val      = Regex.Replace(x1.Value, @"\s", "");
            string expected = String.Format("{{\"Value2\":\"abc\",\"$\":\"{0}\"}}", instance);

            Assert.Equal(expected, val);
        }