using NUnit.Framework;
using System;
using Mono.Documentation;
using System.Xml;
using System.Xml.XPath;
using System.Linq;
using Mono.Cecil;
using System.Collections.Generic;
using Mono.Documentation.Updater.Frameworks;
using Mono.Documentation.Updater;
using System.Runtime.InteropServices;
using Mono.Documentation.Updater.Formatters;
namespace mdoc.Test
{
public class OneAttribute : Attribute { }
public class TwoAttribute : Attribute { }
[One]
public class MyClass
{
[One]
public void Meth (int a, string d, int c) { }
}
public class MyClass2
{
public void Meth (int a, string b, int c) { }
}
public class MyComplicatedClass
{
public IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback cback, object state) => null;
}
}
namespace mdoc.Test2
{
using mdoc.Test;
[One, Two]
public class MyClass
{
[One, Two]
public void Meth (int a, string b, int c) { }
}
[Two]
public class MyClass2
{
[Two]
public void Meth (int d, string e, int f) { }
}
}
namespace mdoc.Test3
{
public class MyClass
{
public void Meth(int a, string b, int c) { }
}
public class MyClass2
{
public void Meth(int A, string B, int C) { }
}
}
namespace mdoc.Test
{
///
/// Tests functions that update the EcmaXMl under various conditions from
/// corresponding classes.
///
[TestFixture ()]
public class XmlUpdateTests
{
class ParamContext {
public XmlDocument doc;
public string beforeXML;
public MethodReference method;
public List parameters;
public MDocUpdater updater;
public FrameworkIndex fx;
}
#region Myclass Tests
[Test ()]
public void Parameters_Updating_Normal ()
{
var context = InitContext (startingEmptyXml, 0);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First ();
context.fx.Frameworks.RemoveAt(2);
context.fx.Frameworks.RemoveAt(1);
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize(normalSingleXml), afterXML);
}
[Test ()]
public void Parameters_Updating_Existing_MultiFramework ()
{
var context = InitContext (multiFrameworkXml, 0);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
// the original state was cleared out on account that this was the first of the frameworks
Assert.AreEqual (Normalize(XmlConsts.NormalSingleXml), Normalize(afterXML));
}
#endregion
#region MyClass2 tests
[Test ()]
public void Parameters2_Updating_Normal ()
{
var context = InitContext (startingEmptyXml, 0);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize (XmlConsts.NormalSingleXml2), afterXML);
}
[Test ()]
public void Parameters_Updating_Normal22 ()
{
var context = InitContext (XmlConsts.NormalSingleXml2, 1);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize (XmlConsts.MultiFrameworkXml2Second), afterXML);
}
[Test ()]
public void Parameters_Updating_Normal32 ()
{
var context = InitContext (XmlConsts.MultiFrameworkXml2Second, 2);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[2].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize (XmlConsts.MultiFrameworkXml2), afterXML);
}
[Test()]
public void Parameters_Updating_BeginRead()
{
FrameworkIndex fx = new FrameworkIndex("", 3, null);
fx.Frameworks.Add(new FrameworkEntry(fx.Frameworks, fx.Frameworks) { Id = "One", Name = "One", Replace = "mdoc.Test2", With = "mdoc.Test" });
fx.Frameworks.Add(new FrameworkEntry(fx.Frameworks, fx.Frameworks) { Id = "Two", Name = "Two", Replace = "mdoc.Test2", With = "mdoc.Test" });
fx.Frameworks.Add(new FrameworkEntry(fx.Frameworks, fx.Frameworks) { Id = "Three", Name = "Three", Replace = "mdoc.Test2", With = "mdoc.Test" });
var context = InitComplexContext(XmlConsts.XML_METHOD_TESTMETHOD_BEFORE, "mdoc.Test", "BeginRead", fx);
var theType = context.method.DeclaringType.Resolve();
foreach (var it in fx.Frameworks)
{
var t = it.ProcessType(theType, theType.Module.Assembly);
foreach(var m in theType.Methods)
{
t.ProcessMember(m);
}
}
var typeEntry = context.fx.Frameworks[2].Types.First();
bool fxAlternateTriggered = true;
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
// TODO: make representative post-method XML
Assert.AreEqual(Normalize(XmlConsts.XML_METHOD_TESTMETHOD_AFTER), afterXML);
}
[Test ()]
public void Parameters_Updating_Existing_MultiFramework22 ()
{
var context = InitContext (XmlConsts.MultiFrameworkXml2, 0);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize(XmlConsts.NormalSingleXml2), Normalize (afterXML));
}
[Test ()]
public void Parameters_Updating_Existing_MultiFramework222 ()
{
var context = InitContext (XmlConsts.MultiFrameworkXml2, 2);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[2].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.AreEqual (context.beforeXML, Normalize (afterXML));
}
[Test ()]
public void Parameters_Updating_Existing_Align2 ()
{
var context = InitContext (XmlConsts.MultiFrameworkXml2, 1, forceAlignment: true);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.IsFalse (fxAlternateTriggered);
Assert.AreEqual (Normalize (XmlConsts.MultiFrameworkAligned2), Normalize (afterXML));
}
#endregion
#region Simple Parameter Change across multi FX
[Test ()]
public void Parameters_Updating_Existing_NameChange ()
{
var context = InitContext (XmlConsts.NormalSingleXml2, 1, forceAlignment: false);
Func typeEntry = i => context.fx.Frameworks[i].Types.First ();
bool fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry(0), ref fxAlternateTriggered);
// this will be false, since it clears out the parameters list on the first run
Assert.IsFalse (fxAlternateTriggered, "first run");
fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry (1), ref fxAlternateTriggered);
Assert.IsFalse (fxAlternateTriggered, "second run");
fxAlternateTriggered = false;
context.updater.MakeParameters (context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry (2), ref fxAlternateTriggered);
Assert.IsFalse (fxAlternateTriggered, "third run");
var afterXML = context.doc.OuterXml;
Assert.AreEqual (Normalize (XmlConsts.MultiFrameworkAlignedOther), Normalize (afterXML));
}
#endregion
#region Parameter Name Alpha Diff
[Test()]
public void Parameters3_Making_NameDiff()
{
var context = InitContext(startingEmptyXml, 0, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3");
var context2 = InitContext(startingEmptyXml, 1, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3");
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First();
FrameworkTypeEntry typeEntry2 = context.fx.Frameworks[1].Types.First();
bool fxAlternateTriggered = false;
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context2.method, context2.parameters, typeEntry2, ref fxAlternateTriggered);
var afterXML = context.doc.OuterXml;
Assert.IsTrue(afterXML.Contains("Parameter Name=\"a\""), "missing 'a'");
Assert.IsTrue(afterXML.Contains("Parameter Name=\"b\""), "missing 'b'");
Assert.IsTrue(afterXML.Contains("Parameter Name=\"c\""), "missing 'c'");
Assert.IsTrue(afterXML.Contains("Parameter Name=\"A\""), "missing 'A'");
Assert.IsTrue(afterXML.Contains("Parameter Name=\"B\""), "missing 'B'");
Assert.IsTrue(afterXML.Contains("Parameter Name=\"C\""), "missing 'C'");
}
[Test()]
public void Parameters3_Updating_NameDiff()
{
var context = InitContext(startingEmptyXml, 0, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3");
var context2 = InitContext(startingEmptyXml, 1, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3");
var context3 = InitContext(startingEmptyXml, 2, false, ns1: "mdoc.Test3", ns2: "mdoc.Test3");
FrameworkTypeEntry typeEntry = context.fx.Frameworks[0].Types.First();
FrameworkTypeEntry typeEntry2 = context.fx.Frameworks[1].Types.First();
FrameworkTypeEntry typeEntry3 = context.fx.Frameworks[2].Types.First();
bool fxAlternateTriggered = false;
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context.method, context.parameters, typeEntry, ref fxAlternateTriggered);
context.updater.UpdateParameters(context.doc.FirstChild as XmlElement, "param", context.parameters.Select(p => p.Name).ToArray(), typeEntry);
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context2.method, context2.parameters, typeEntry2, ref fxAlternateTriggered);
context.updater.UpdateParameters(context.doc.FirstChild as XmlElement, "param", context2.parameters.Select(p => p.Name).ToArray(), typeEntry2);
context.updater.MakeParameters(context.doc.FirstChild as XmlElement, context3.method, context3.parameters, typeEntry3, ref fxAlternateTriggered);
context.updater.UpdateParameters(context.doc.FirstChild as XmlElement, "param", context3.parameters.Select(p => p.Name).ToArray(), typeEntry3);
var afterXML = context.doc.OuterXml;
Assert.IsTrue(afterXML.Contains("param name=\"a\""), "missing 'a'");
Assert.IsTrue(afterXML.Contains("param name=\"b\""), "missing 'b'");
Assert.IsTrue(afterXML.Contains("param name=\"c\""), "missing 'c'");
Assert.IsTrue(afterXML.Contains("param name=\"A\""), "missing 'A'");
Assert.IsTrue(afterXML.Contains("param name=\"B\""), "missing 'B'");
Assert.IsTrue(afterXML.Contains("param name=\"C\""), "missing 'C'");
}
#endregion
[Test ()]
public void DocMemberEnumerator()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 1, forceAlignment: true);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[1].Types.First ();
var enumerator = new DocumentationEnumerator ();
var matches = enumerator.GetDocumentationMembers (context.doc, context.method.DeclaringType.Resolve (), typeEntry);
Assert.IsTrue (matches.Any (m => m.Member == context.method && m.Node != null), "didn't match the member");
}
[Test ()]
public void DocMemberEnumerator2 ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: true);
FrameworkTypeEntry typeEntry = context.fx.Frameworks[2].Types.First ();
var enumerator = new DocumentationEnumerator ();
var matches = enumerator.GetDocumentationMembers (context.doc, context.method.DeclaringType.Resolve (), typeEntry);
Assert.IsTrue (matches.Any (m => m.Member == context.method && m.Node != null), "didn't match the member");
}
[Test]
public void Attributes_TypeOrMethod()
{
var context = InitContext(string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First();
var attributeList = new[] { ((CustomAttribute)null, "One") };
MDocUpdater.MakeAttributes(context.doc.FirstChild as XmlElement, attributeList, typeEntry);
var attrNode = context.doc.FirstChild.SelectSingleNode("Attributes");
var attributes = attrNode.SelectNodes("Attribute").Cast().ToArray();
Assert.IsTrue(attributes.Count() == 1);
Assert.AreEqual("[One]", attributes[0].FirstChild.InnerText);
Assert.AreEqual("Three", attributes[0].GetAttribute(Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
foreach (var fx in context.fx.Frameworks)
{
//var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_OneMissing ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
foreach (var fx in context.fx.Frameworks)
{
//var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (fx.IsFirstFramework)
attributeList = null;
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Three;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_OneMissing_Last ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
foreach (var fx in context.fx.Frameworks)
{
//var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (fx.IsLastFramework)
attributeList = null;
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("One;Three", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_RunExisting_Middle ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
// first, go through and add "One" and "Two" to all of them
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
// Now, to test the first deployment on an existing set
// in this case, the truth of the matter is that `Two` only exists in the middle
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (!fx.IsFirstFramework && !fx.IsLastFramework) {
attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
}
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("[Two]", attributes[1].FirstChild.InnerText);
Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Three", attributes[1].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_RunExisting_First ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
// first, go through and add "One" and "Two" to all of them
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
// Now, to test the first deployment on an existing set
// in this case, the truth of the matter is that `Two` only exists in the middle
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (fx.IsFirstFramework)
{
attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
}
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("[Two]", attributes[1].FirstChild.InnerText);
Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("One", attributes[1].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_RunExisting_Last ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
// first, go through and add "One" and "Two" to all of them
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "Two") };
if (fx.IsLastFramework)
{
attributeList = new[] { ((CustomAttribute)null, "One"), ((CustomAttribute)null, "Two") };
}
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 2);
Assert.AreEqual ("[One]", attributes[1].FirstChild.InnerText);
Assert.IsTrue (attributes[1].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("Two", attributes[1].GetAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("[Two]", attributes[0].FirstChild.InnerText);
Assert.IsFalse (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
[Test]
public void Attributes_TypeOrMethod_AllFX_OneMissing_Middle ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
foreach (var fx in context.fx.Frameworks)
{
//var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (!fx.IsLastFramework && !fx.IsFirstFramework)
attributeList = null;
MDocUpdater.MakeAttributes (context.doc.FirstChild as XmlElement, attributeList, typeEntry);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("[One]", attributes[0].FirstChild.InnerText);
Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("One;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
[Ignore("Unable to mock valid AssemblySet, ignore for now")]
public void Attributes_Assembly ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
foreach (var fx in context.fx.Frameworks)
{
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
if (!fx.IsLastFramework && !fx.IsFirstFramework)
{
attributeList = null;
}
MDocUpdater.MakeAttributes(
context.doc.FirstChild as XmlElement,
attributeList,
fx.IsFirstFrameworkForAssembly("one.dll"),
fx.IsLastFrameworkForAssembly("one.dll"),
() => fx.AllFrameworksStringWithAssembly("one.dll"),
null,
perLanguage: false);
}
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
Assert.AreEqual ("One;Two", attributes[0].GetAttribute (Consts.FrameworkAlternate));
}
[Test]
[Ignore("Unable to mock valid AssemblySet, ignore for now")]
public void Attributes_Assembly_OtherAssembly ()
{
var context = InitContext (string.Format (typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First ();
var attributeList = new[] { ((CustomAttribute)null, "One") };
// this is the 'second' fx, and we've changed the expected assembly name,
// so the attribute, while it doesn't exist yet, shouldn't have an FX made since it doesn't exist in any other FX
MDocUpdater.MakeAttributes(
context.doc.FirstChild as XmlElement,
attributeList,
fx.IsFirstFrameworkForAssembly("one.dll"),
fx.IsLastFrameworkForAssembly("one.dll"),
() => fx.AllFrameworksStringWithAssembly("one.dll"),
null,
perLanguage: false);
var attrNode = context.doc.FirstChild.SelectSingleNode ("Attributes");
var attributes = attrNode.SelectNodes ("Attribute").Cast ().ToArray ();
Assert.IsTrue (attributes.Count () == 1);
Assert.AreEqual ("One", attributes[0].FirstChild.InnerText);
Assert.IsTrue (attributes[0].HasAttribute (Consts.FrameworkAlternate));
}
[Test]
public void FxElementTest()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"old value");
var context = InitContext(string.Format(typeFrameXml, multiFrameworkXml), 0, forceAlignment: false);
var fx = context.fx.Frameworks[0];
FrameworkTypeEntry typeEntry = fx.Types.First();
XmlElement parentx = doc.DocumentElement;
DocUtils.AddElementWithFx(
typeEntry,
parentx,
isFirst: typeEntry.Framework.IsFirstFrameworkForType(typeEntry),
isLast: typeEntry.Framework.IsLastFrameworkForType(typeEntry),
allfxstring: new Lazy(() => typeEntry.Framework.AllFrameworksWithType(typeEntry)),
clear: parent =>
{
parent.RemoveAll();
},
findExisting: parent =>
{
return parent.SelectSingleNode("X") as XmlElement;
},
addItem: parent =>
{
var item = parent.OwnerDocument.CreateElement("X");
item.InnerText = "value";
parent.AppendChild(item);
return item;
});
Assert.AreEqual(1, parentx.ChildNodes.Count);
Assert.AreEqual("value", parentx.ChildNodes[0].InnerText);
Assert.AreEqual("One", parentx.ChildNodes[0].Attributes[0].Value);
}
[Test]
public void FxElementTest_Two()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"old value");
var context = InitContext(string.Format(typeFrameXml, multiFrameworkXml), 0, forceAlignment: false);
var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First();
XmlElement parentx = doc.DocumentElement;
System.Func runfx = (te, value) =>
{
DocUtils.AddElementWithFx(
te,
parentx,
isFirst: te.Framework.IsFirstFrameworkForType(te),
isLast: te.Framework.IsLastFrameworkForType(te),
allfxstring: new Lazy(() => typeEntry.Framework.AllFrameworksWithType(typeEntry)),
clear: parent =>
{
parent.RemoveAll();
},
findExisting: parent =>
{
return parent.ChildNodes.Cast().SingleOrDefault(e => e.Name == "X" && e.Value == value);
},
addItem: parent =>
{
var item = parent.OwnerDocument.CreateElement("X");
item.InnerText = value;
parent.AppendChild(item);
return item;
});
return true;
};
runfx(context.fx.Frameworks[0].Types.First(), "one");
runfx(context.fx.Frameworks[1].Types.First(), "two");
Assert.AreEqual(parentx.ChildNodes.Count, 2);
Assert.IsTrue(parentx.ChildNodes.Cast().Any(e => e.HasAttribute(Consts.FrameworkAlternate)), "fx check");
}
[Test]
public void FxElementTest_Three()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"old value");
var context = InitContext(string.Format(typeFrameXml, multiFrameworkXml), 2, forceAlignment: false);
var fx = context.fx.Frameworks[1];
FrameworkTypeEntry typeEntry = fx.Types.First();
XmlElement parentx = doc.DocumentElement;
System.Func runfx = (te) =>
{
DocUtils.AddElementWithFx(
te,
parentx,
isFirst: typeEntry.Framework.IsFirstFrameworkForType(typeEntry),
isLast: typeEntry.Framework.IsLastFrameworkForType(typeEntry),
allfxstring: new Lazy(() => typeEntry.Framework.AllFrameworksWithType(typeEntry)),
clear: parent =>
{
parent.RemoveAll();
},
findExisting: parent =>
{
return parent.SelectSingleNode("X") as XmlElement;
},
addItem: parent =>
{
var item = parent.OwnerDocument.CreateElement("X");
item.InnerText = "value";
parent.AppendChild(item);
return item;
});
return true;
};
runfx(context.fx.Frameworks[0].Types.First());
runfx(context.fx.Frameworks[1].Types.First());
runfx(context.fx.Frameworks[2].Types.First());
Assert.AreEqual(parentx.ChildNodes.Count, 1);
}
string Normalize(string xml, bool clearFx = false) {
XmlDocument doc = new XmlDocument ();
doc.LoadXml (xml);
return doc.OuterXml;
}
string typeFrameXml = @"{0}";
#region MyClass XML
string startingEmptyXml = @"
Method
System.Void
To be added.
To be added.
";
string normalSingleXml = @"
Method
System.Void
To be added.
To be added.
";
string multiFrameworkXml = @"
Method
System.Void
To be added.
To be added.
";
string multiFrameworkAligned = @"
Method
System.Void
To be added.
To be added.
";
#endregion
string SigmultiFrameworkXml = @"
";
string SigmultiFrameworkAligned = @"
";
string SigRegular = @"
";
string SigRegularChanged = @"
";
string SigRegularAllAligned = @"
";
private ParamContext InitComplexContext(string methodXml, string ns, string methodName, FrameworkIndex fx)
{
var doc = new XmlDocument();
doc.LoadXml(methodXml);
var beforeXML = doc.OuterXml;
TypeDefinition type = GetDefinition(ns);
var method = type.Methods.First(m => m.Name == methodName) as MethodReference;
var updater = new MDocUpdater();
return new ParamContext()
{
doc = doc,
beforeXML = beforeXML,
method = method,
parameters = method.Parameters.ToList(),
fx = fx,
updater = updater
};
}
private ParamContext InitContext (string methodXml, int fxIndex, bool forceAlignment=false, string ns1="mdoc.Test", string ns2="mdoc.Test2")
{
Func indexCheck = fi => fi < 2;
if (typeof(T) == typeof(MyClass2))
indexCheck = fi => fi != 1;
bool useFirst = forceAlignment || indexCheck(fxIndex);
var doc = new XmlDocument ();
//doc.PreserveWhitespace = true;
doc.LoadXml (methodXml);
var beforeXML = doc.OuterXml;
XmlElement root = doc.SelectSingleNode ("//Docs") as XmlElement; // Docs
TypeDefinition type = GetDefinition (ns1);
var method = type.Methods.First (m => m.Name == "Meth") as MethodReference;
var parameters = method.Parameters.ToList ();
TypeDefinition type2 = GetDefinition (ns2);
var method2 = type2.Methods.First (m => m.Name == "Meth") as MethodReference;
var parameters2 = method2.Parameters.ToList ();
// updater
var updater = new MDocUpdater ();
var fx = new FrameworkIndex ("", 3, null);
fx.Frameworks.Add (new FrameworkEntry (fx.Frameworks, fx.Frameworks) { Id = "One", Name = "One", Replace=ns2, With=ns1 });
fx.Frameworks.Add (new FrameworkEntry (fx.Frameworks, fx.Frameworks) { Id = "Three", Name = "Three", Replace = ns2, With = ns1 });
fx.Frameworks.Add (new FrameworkEntry (fx.Frameworks, fx.Frameworks) { Id = "Two", Name = "Two", Replace = ns2, With = ns1 });
var i = 0;
foreach (var f in fx.Frameworks)
{
if (indexCheck(i) || forceAlignment)
{
var t = f.ProcessType (type, type.Module.Assembly);
t.ProcessMember (method);
var aset = new AssemblySet (new[] { "one.dll" });
f.AddAssemblySet (aset);
}
else {
var t = f.ProcessType (type2, type2.Module.Assembly);
t.ProcessMember (method2);
}
i++;
}
updater.InitializeFrameworksCache (fx);
return new ParamContext ()
{
doc = doc,
beforeXML = beforeXML,
method = useFirst ? method : method2,
parameters = useFirst ? parameters : parameters2,
fx = fx,
updater = updater
};
}
TypeDefinition GetDefinition(string ns)
{
Type t = typeof (T);
string path = t.Assembly.Location;
AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly (path);
return assembly.MainModule.Types.First (type =>
type.Name == t.Name && type.Namespace == ns);
}
}
}