using NUnit.Framework; using System.Linq; using mdoc.Test.SampleClasses; using Mono.Documentation.Updater; namespace mdoc.Test { [TestFixture ()] public class FormatterTests : BasicFormatterTests { private CSharpMemberFormatter csharpMemberFormatter = new CSharpMemberFormatter(); protected override CSharpMemberFormatter formatter => csharpMemberFormatter; [Test ()] public void Formatters_VerifyPrivateConstructorNull () { // this is a private constructor var method = GetMethod (typeof(TestClass), m => m.IsConstructor && !m.IsPublic && m.Parameters.Count () == 1); MemberFormatter[] formatters = new MemberFormatter[] { new CSharpFullMemberFormatter (), new CSharpMemberFormatter(), new ILMemberFormatter(), new ILFullMemberFormatter(), new VBFullMemberFormatter (), new VBMemberFormatter(), new FSharpMemberFormatter(), new FSharpFullMemberFormatter(), }; var sigs = formatters.Select (f => f.GetDeclaration (method)); foreach (var sig in sigs) Assert.IsNull (sig); } [Test] public void CSharp_op_Addition () => TestBinaryOp ("Addition", "+"); [Test] public void CSharp_op_Subtraction () => TestBinaryOp ("Subtraction", "-"); [Test] public void CSharp_op_Division () => TestBinaryOp ("Division", "/"); [Test] public void CSharp_op_Multiplication () => TestBinaryOp ("Multiply", "*"); [Test] public void CSharp_op_Modulus () => TestBinaryOp ("Modulus", "%"); [Test] public void CSharp_op_BitwiseAnd () => TestBinaryOp ("BitwiseAnd", "&"); [Test] public void CSharp_op_BitwiseOr () => TestBinaryOp ("BitwiseOr", "|"); [Test] public void CSharp_op_ExclusiveOr () => TestBinaryOp ("ExclusiveOr", "^"); [Test] public void CSharp_op_LeftShift () => TestBinaryOp ("LeftShift", "<<", secondType: "int"); [Test] public void CSharp_op_RightShift () => TestBinaryOp ("RightShift", ">>", secondType: "int"); [Test] public void CSharp_op_UnaryPlus () => TestUnaryOp ("UnaryPlus", "+"); [Test] public void CSharp_op_UnaryNegation () => TestUnaryOp ("UnaryNegation", "-"); [Test] public void CSharp_op_LogicalNot () => TestUnaryOp ("LogicalNot", "!"); [Test] public void CSharp_op_OnesComplement () => TestUnaryOp ("OnesComplement", "~"); [Test] public void CSharp_op_Decrement () => TestUnaryOp ("Decrement", "--"); [Test] public void CSharp_op_Increment () => TestUnaryOp ("Increment", "++"); [Test] public void CSharp_op_True () => TestUnaryOp ("True", "true", returnType: "bool"); [Test] public void CSharp_op_False () => TestUnaryOp ("False", "false", returnType: "bool"); [Test] public void CSharp_op_Equality () => TestComparisonOp ("Equality", "=="); [Test] public void CSharp_op_Inequality () => TestComparisonOp ("Inequality", "!="); [Test] public void CSharp_op_LessThan () => TestComparisonOp ("LessThan", "<"); [Test] public void CSharp_op_GreaterThan () => TestComparisonOp ("GreaterThan", ">"); [Test] public void CSharp_op_LessThanOrEqual () => TestComparisonOp ("LessThanOrEqual", "<="); [Test] public void CSharp_op_GreaterThanOrEqual () => TestComparisonOp ("GreaterThanOrEqual", ">="); [Test] public void CSharp_op_Implicit () => TestConversionOp ("Implicit", "implicit", "TestClass", "TestClassTwo"); [Test] public void CSharp_op_Implicit_inverse () => TestConversionOp ("Implicit", "implicit", "TestClassTwo", "TestClass"); [Test] public void CSharp_op_Explicit () => TestConversionOp ("Explicit", "explicit", "int", "TestClass"); [Test] public void CSharp_op_Explicit_inverse () => TestConversionOp ("Explicit", "explicit", "TestClass", "int"); [Test] public void CSharp_modopt () => TestMod ("SomeFunc2", "public SomeClass* SomeFunc2 (SomeClass param);", returnType: "SomeClass*"); [Test] public void CSharp_modreq () => TestMod ("SomeFunc", "public int SomeFunc (SomeClass* param);", returnType: "int"); [Test] public void CSharp_doublepointer () => TestMod ("SomeFunc3", "public SomeClass** SomeFunc3 (int param);", returnType: "cppcli.SomeClass**"); [Test] public void CSharp_pointerref_modreqparam () => TestMod ("SomeFunc4", "public int SomeFunc4 (SomeClass** param, int param2);", returnType: "int"); [Test] public void DoubleMod () { string doubledUp = "System.ValueType modopt(System.DateTime) modopt(System.Runtime.CompilerServices.IsBoxed)"; string result = MemberFormatter.RemoveMod (doubledUp); Assert.AreEqual ("System.ValueType", result); } [Test] public void DoubleMod_Mixed () { string doubledUp = "System.ValueType modreq(System.DateTime) modopt(System.Runtime.CompilerServices.IsBoxed)"; string result = MemberFormatter.RemoveMod (doubledUp); Assert.AreEqual ("System.ValueType", result); } [Test] public void DoubleMod_Pointer () { string doubledUp = "System.ValueType modreq(System.DateTime) modopt(System.Runtime.CompilerServices.IsBoxed)*"; string result = MemberFormatter.RemoveMod (doubledUp); Assert.AreEqual ("System.ValueType*", result); } [Test] public void Params() { var member = GetMethod (typeof(TestClass), m => m.Name == "DoSomethingWithParams"); var sig = formatter.GetDeclaration (member); Assert.AreEqual ("public void DoSomethingWithParams (params int[] values);", sig); } [Test] public void IL_RefAndOut () { var member = GetMethod (typeof(TestClass), m => m.Name == "RefAndOut"); var formatter = new ILFullMemberFormatter (); var sig = formatter.GetDeclaration (member); Assert.AreEqual (".method public hidebysig instance void RefAndOut(int32& a, [out] int32& b) cil managed", sig); } #region Helper Methods string RealTypeName(string name){ switch (name) { case "bool": return "Boolean"; case "int": return "Int32"; default: return name; } } void TestConversionOp (string name, string type, string leftType, string rightType) { TestOp (name, $"public static {type} operator {leftType} ({rightType} c1);", argCount: 1, returnType: leftType); } void TestComparisonOp (string name, string op) { TestOp (name, $"public static bool operator {op} (TestClass c1, TestClass c2);", argCount: 2, returnType: "Boolean"); } void TestUnaryOp (string name, string op, string returnType = "TestClass") { TestOp (name, $"public static {returnType} operator {op} (TestClass c1);", argCount: 1, returnType: returnType); } void TestBinaryOp (string name, string op, string returnType = "TestClass", string secondType = "TestClass") { TestOp (name, $"public static {returnType} operator {op} (TestClass c1, {secondType} c2);", argCount: 2, returnType: returnType); } void TestOp (string name, string expectedSig, int argCount, string returnType = "TestClass") { var member = GetMethod (typeof(TestClass), m => m.Name == $"op_{name}" && m.Parameters.Count == argCount && m.ReturnType.Name == RealTypeName (returnType)); var formatter = new CSharpMemberFormatter (); var sig = formatter.GetDeclaration (member); Assert.AreEqual (expectedSig, sig); } void TestMod (string name, string expectedSig, int argCount = 1, string returnType = "SomeClass") { var member = GetMethod ( GetType ("SampleClasses/cppcli.dll", "cppcli.SomeInterface"), m => m.Name == name ); var formatter = new CSharpMemberFormatter (); var sig = formatter.GetDeclaration (member); Assert.AreEqual (expectedSig, sig); } #endregion } }