private CodeTypeDeclaration GetGeneratedClass(MultiDirectionTestClass testClass)
        {
            CodeTypeDeclaration result = new CodeTypeDeclaration(this.GetGeneratedClassName(testClass));
            result.Attributes = MemberAttributes.Public;
            result.BaseTypes.Add(testClass.ClassType);

            CodeAttributeDeclaration testClassAttribute = new CodeAttributeDeclaration(
                new CodeTypeReference(typeof(TestClassAttribute)));

            result.CustomAttributes.Add(testClassAttribute);

            // Add initialize and cleanup method
            result.Members.Add(this.GetInitCleanupMethod(typeof(ClassInitializeAttribute), testClass));
            result.Members.Add(this.GetInitCleanupMethod(typeof(ClassCleanupAttribute), testClass));

            // No need to generate TestInitialize and TestCleanup Method.
            // Generated class can inherit from base class.

            // Expand multiple direction test case
            foreach (MultiDirectionTestMethod testMethod in testClass.MultiDirectionMethods)
            {
                this.AddGeneratedMethod(result, testMethod);
            }

            return result;
        }
        private static void GenerateCode(string dllName, string outputFolder)
        {
            SourceCodeGenerator codeGen = new SourceCodeGenerator(outputFolder);

            Assembly assembly = Assembly.LoadFrom(dllName);

            foreach (Type type in assembly.GetTypes())
            {
                if (null != type.GetCustomAttribute(typeof(MultiDirectionTestClassAttribute)))
                {
                    MultiDirectionTestClass testClass = new MultiDirectionTestClass(type);
                    codeGen.GenerateSourceCode(testClass);
                }
            }
        }
        public void GenerateSourceCode(MultiDirectionTestClass testClass)
        {
            string sourceFileName = this.GetSourceFileName(testClass);

            if (testClass.MultiDirectionMethods.Count == 0)
            {
                Console.WriteLine("{0} has no multiple direction test case. Skip code generating...", testClass.ClassType.Name);
                return;
            }

            Console.WriteLine("Generating code for {0}", testClass.ClassType.Name);

            CodeCompileUnit compileUnit = new CodeCompileUnit();
            CodeNamespace rootNameSpace = new CodeNamespace(GodeGeneratorConst.RootNameSpace);

            this.AddImport(rootNameSpace);

            rootNameSpace.Types.Add(GetGeneratedClass(testClass));

            compileUnit.Namespaces.Add(rootNameSpace);

            this.WriteCodeToFile(compileUnit, Path.Combine(this.outputPath, sourceFileName));
        }
        private CodeMemberMethod GetInitCleanupMethod(Type methodAttributeType, MultiDirectionTestClass testClass)
        {
            bool isStatic = false;
            string generatedMetholdName = string.Empty;
            string methodToInvokeName = string.Empty;
            CodeParameterDeclarationExpression parameterDec = null;

            if (methodAttributeType == typeof(ClassInitializeAttribute))
            {
                isStatic = true;
                generatedMetholdName = GodeGeneratorConst.ClassInitMethodName;
                methodToInvokeName = testClass.ClassInit.Name;
                parameterDec = new CodeParameterDeclarationExpression(typeof(TestContext), "testContext");
            }
            else if (methodAttributeType == typeof(ClassCleanupAttribute))
            {
                isStatic = true;
                generatedMetholdName = GodeGeneratorConst.ClassCleanupMethodName;
                methodToInvokeName = testClass.ClassCleanup.Name;
            }
            else
            {
                throw new ArgumentException("methodAttributeType");
            }

            CodeMemberMethod result = new CodeMemberMethod();
            result.Name = generatedMetholdName;

            // Add parameter list if needed
            if (parameterDec != null)
            {
                result.Parameters.Add(parameterDec);
            }

            CodeExpression callBase = null;
            if (isStatic)
            {
                result.Attributes = MemberAttributes.Public | MemberAttributes.Static;
                callBase = new CodeTypeReferenceExpression(testClass.ClassType.FullName);
            }
            else
            {
                result.Attributes = MemberAttributes.Public | MemberAttributes.Final;
                callBase = new CodeBaseReferenceExpression();
            }

            // Add methold attribute
            CodeAttributeDeclaration methodAttribute = new CodeAttributeDeclaration(
                new CodeTypeReference(methodAttributeType));
            result.CustomAttributes.Add(methodAttribute);

            // Add invoke statement
            CodeMethodInvokeExpression invokeExp = null;
            if (parameterDec != null)
            {
                CodeVariableReferenceExpression sourceParameter = new CodeVariableReferenceExpression(parameterDec.Name);
                invokeExp = new CodeMethodInvokeExpression(callBase, methodToInvokeName, sourceParameter);
            }
            else
            {
                invokeExp = new CodeMethodInvokeExpression(callBase, methodToInvokeName);
            }

            result.Statements.Add(invokeExp);

            return result;
        }
 private string GetGeneratedClassName(MultiDirectionTestClass testClass)
 {
     return testClass.ClassType.Name + GeneratedSuffix;
 }
 private string GetSourceFileName(MultiDirectionTestClass testClass)
 {
     return this.GetGeneratedClassName(testClass) + SourceFileExtention;
 }