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)); } }
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); }
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); }
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); }
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>()); }
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); }
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. }
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)); }
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 }
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>()); }
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>()); }
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)); }
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); }
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); }
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); }
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); }
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); } }
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); } }
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); }
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); }