Files
Umbraco-CMS/src/Umbraco.Tests/Mapping/MappingTests.cs

299 lines
9.1 KiB
C#
Raw Normal View History

2019-04-15 10:25:29 +02:00
using System;
using System.Collections.Generic;
2019-03-20 19:09:23 +01:00
using System.Linq;
2019-04-15 10:25:29 +02:00
using System.Threading;
2019-03-20 19:09:23 +01:00
using NUnit.Framework;
using Umbraco.Core.Mapping;
2019-04-08 10:05:21 +02:00
using Umbraco.Core.Models;
using Umbraco.Web.Models.ContentEditing;
2019-03-20 19:09:23 +01:00
namespace Umbraco.Tests.Mapping
{
[TestFixture]
public class MappingTests
{
[Test]
public void SimpleMap()
{
2019-04-08 10:05:21 +02:00
var definitions = new MapDefinitionCollection(new IMapDefinition[]
2019-03-20 19:09:23 +01:00
{
2019-04-08 10:05:21 +02:00
new MapperDefinition1(),
2019-03-20 19:09:23 +01:00
});
2019-04-08 10:05:21 +02:00
var mapper = new UmbracoMapper(definitions);
2019-03-20 19:09:23 +01:00
var thing1 = new Thing1 { Value = "value" };
var thing2 = mapper.Map<Thing1, Thing2>(thing1);
Assert.IsNotNull(thing2);
Assert.AreEqual("value", thing2.Value);
thing2 = mapper.Map<Thing2>(thing1);
Assert.IsNotNull(thing2);
Assert.AreEqual("value", thing2.Value);
thing2 = new Thing2();
mapper.Map(thing1, thing2);
Assert.AreEqual("value", thing2.Value);
}
[Test]
public void EnumerableMap()
{
2019-04-08 10:05:21 +02:00
var definitions = new MapDefinitionCollection(new IMapDefinition[]
2019-03-20 19:09:23 +01:00
{
2019-04-08 10:05:21 +02:00
new MapperDefinition1(),
2019-03-20 19:09:23 +01:00
});
2019-04-08 10:05:21 +02:00
var mapper = new UmbracoMapper(definitions);
2019-03-20 19:09:23 +01:00
var thing1A = new Thing1 { Value = "valueA" };
var thing1B = new Thing1 { Value = "valueB" };
var thing1 = new[] { thing1A, thing1B };
var thing2 = mapper.Map<IEnumerable<Thing1>, IEnumerable<Thing2>>(thing1).ToList();
Assert.IsNotNull(thing2);
Assert.AreEqual(2, thing2.Count);
Assert.AreEqual("valueA", thing2[0].Value);
Assert.AreEqual("valueB", thing2[1].Value);
thing2 = mapper.Map<IEnumerable<Thing2>>(thing1).ToList();
Assert.IsNotNull(thing2);
Assert.AreEqual(2, thing2.Count);
Assert.AreEqual("valueA", thing2[0].Value);
Assert.AreEqual("valueB", thing2[1].Value);
2019-04-08 16:38:18 +02:00
thing2 = mapper.MapEnumerable<Thing1, Thing2>(thing1).ToList();
Assert.IsNotNull(thing2);
Assert.AreEqual(2, thing2.Count);
Assert.AreEqual("valueA", thing2[0].Value);
Assert.AreEqual("valueB", thing2[1].Value);
2019-03-20 19:09:23 +01:00
}
2019-03-26 18:47:35 +01:00
[Test]
public void InheritedMap()
{
2019-04-08 10:05:21 +02:00
var definitions = new MapDefinitionCollection(new IMapDefinition[]
2019-03-26 18:47:35 +01:00
{
2019-04-08 10:05:21 +02:00
new MapperDefinition1(),
2019-03-26 18:47:35 +01:00
});
2019-04-08 10:05:21 +02:00
var mapper = new UmbracoMapper(definitions);
2019-03-26 18:47:35 +01:00
var thing3 = new Thing3 { Value = "value" };
var thing2 = mapper.Map<Thing3, Thing2>(thing3);
Assert.IsNotNull(thing2);
Assert.AreEqual("value", thing2.Value);
thing2 = mapper.Map<Thing2>(thing3);
Assert.IsNotNull(thing2);
Assert.AreEqual("value", thing2.Value);
thing2 = new Thing2();
mapper.Map(thing3, thing2);
Assert.AreEqual("value", thing2.Value);
}
2019-04-08 10:05:21 +02:00
[Test]
public void CollectionsMap()
{
var definitions = new MapDefinitionCollection(new IMapDefinition[]
{
new MapperDefinition2(),
});
var mapper = new UmbracoMapper(definitions);
// can map a PropertyCollection
var source = new PropertyCollection();
var target = mapper.Map<IEnumerable<ContentPropertyDto>>(source);
}
2019-04-15 10:25:29 +02:00
[Test]
[Explicit]
public void ConcurrentMap()
{
var definitions = new MapDefinitionCollection(new IMapDefinition[]
{
new MapperDefinition1(),
new MapperDefinition3(),
});
var mapper = new UmbracoMapper(definitions);
// the mapper currently has a map from Thing1 to Thing2
// because Thing3 inherits from Thing1, it will map a Thing3 instance,
// and register a new map from Thing3 to Thing2,
// thus modifying its internal dictionaries
// if timing is good, and mapper does have non-concurrent dictionaries, it fails
// practically, to reproduce, one needs to add a 1s sleep in the mapper's loop
// hence, this test is explicit
var thing3 = new Thing3 { Value = "value" };
var thing4 = new Thing4();
Exception caught = null;
void ThreadLoop()
{
// keep failing at mapping - and looping through the maps
2019-04-15 10:25:29 +02:00
for (var i = 0; i < 10; i++)
{
try
{
mapper.Map<Thing2>(thing4);
}
catch (Exception e)
{
caught = e;
Console.WriteLine($"{e.GetType().Name} {e.Message}");
}
}
Console.WriteLine("done");
}
var thread = new Thread(ThreadLoop);
thread.Start();
Thread.Sleep(1000);
try
{
Console.WriteLine($"{DateTime.Now:O} mapping");
var thing2 = mapper.Map<Thing2>(thing3);
Console.WriteLine($"{DateTime.Now:O} mapped");
Assert.IsNotNull(thing2);
Assert.AreEqual("value", thing2.Value);
}
finally
{
thread.Join();
}
}
[Test]
public void EnumMap()
{
var definitions = new MapDefinitionCollection(new IMapDefinition[]
{
new MapperDefinition4(),
});
var mapper = new UmbracoMapper(definitions);
var thing5 = new Thing5()
{
Fruit1 = Thing5Enum.Apple,
Fruit2 = Thing5Enum.Banana,
Fruit3= Thing5Enum.Cherry
};
var thing6 = mapper.Map<Thing5, Thing6>(thing5);
Assert.IsNotNull(thing6);
Assert.AreEqual(Thing6Enum.Apple, thing6.Fruit1);
Assert.AreEqual(Thing6Enum.Banana, thing6.Fruit2);
Assert.AreEqual(Thing6Enum.Cherry, thing6.Fruit3);
}
2019-03-20 19:09:23 +01:00
private class Thing1
{
public string Value { get; set; }
}
2019-03-26 18:47:35 +01:00
private class Thing3 : Thing1
{ }
2019-03-20 19:09:23 +01:00
private class Thing2
{
public string Value { get; set; }
}
2019-04-15 10:25:29 +02:00
private class Thing4
{ }
private class Thing5
{
public Thing5Enum Fruit1 { get; set; }
public Thing5Enum Fruit2 { get; set; }
public Thing5Enum Fruit3 { get; set; }
}
private enum Thing5Enum
{
Apple = 0,
Banana = 1,
Cherry = 2
}
private class Thing6
{
public Thing6Enum Fruit1 { get; set; }
public Thing6Enum Fruit2 { get; set; }
public Thing6Enum Fruit3 { get; set; }
}
private enum Thing6Enum
{
Apple = 0,
Banana = 1,
Cherry = 2
}
2019-04-08 10:05:21 +02:00
private class MapperDefinition1 : IMapDefinition
2019-03-20 19:09:23 +01:00
{
2019-04-03 10:39:49 +02:00
public void DefineMaps(UmbracoMapper mapper)
2019-03-20 19:09:23 +01:00
{
mapper.Define<Thing1, Thing2>((source, context) => new Thing2(), Map);
2019-03-20 19:09:23 +01:00
}
private void Map(Thing1 source, Thing2 target, MapperContext context)
2019-03-20 19:09:23 +01:00
{
target.Value = source.Value;
}
}
2019-04-08 10:05:21 +02:00
private class MapperDefinition2 : IMapDefinition
{
public void DefineMaps(UmbracoMapper mapper)
{
mapper.Define<Property, ContentPropertyDto>((source, context) => new ContentPropertyDto(), Map);
}
private static void Map(Property source, ContentPropertyDto target, MapperContext context)
{ }
}
2019-04-15 10:25:29 +02:00
private class MapperDefinition3 : IMapDefinition
{
public void DefineMaps(UmbracoMapper mapper)
{
// just some random things so that the mapper contains things
mapper.Define<int, object>();
mapper.Define<string, object>();
mapper.Define<double, object>();
mapper.Define<UmbracoMapper, object>();
mapper.Define<Property, object>();
}
}
private class MapperDefinition4 : IMapDefinition
{
public void DefineMaps(UmbracoMapper mapper)
{
mapper.Define<Thing5, Thing6>((source, context) => new Thing6(), Map);
mapper.Define<Thing5Enum, Thing6Enum>(
(source, context) => (Thing6Enum)source);
}
private void Map(Thing5 source, Thing6 target, MapperContext context)
{
target.Fruit1 = context.Map<Thing6Enum>(source.Fruit1);
target.Fruit2 = context.Map<Thing6Enum>(source.Fruit2);
target.Fruit3 = context.Map<Thing6Enum>(source.Fruit3);
}
}
2019-03-20 19:09:23 +01:00
}
}