From: Hugh Bellamy Date: Fri, 8 Nov 2019 17:09:40 +0000 (+0000) Subject: Add CodeGenerator tests and fix NREs/bugs (dotnet/corefx#40838) X-Git-Tag: submit/tizen/20210909.063632~11031^2~57 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8dd6b6bcfe236e2b81a8e367bf2b2f154bf97f54;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Add CodeGenerator tests and fix NREs/bugs (dotnet/corefx#40838) * Add CodeGenerator tests and fix NREs/bugs * Reverting empty collection checks * Small typo * Skipping tests on full framework * Some more need to be skipped on framework * Fix test failure * Adding format for ToString Commit migrated from https://github.com/dotnet/corefx/commit/7c867c2fa7887327521f57e3a64b34754d68e390 --- diff --git a/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CodeGenerator.cs b/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CodeGenerator.cs index 01fb668..04b9354 100644 --- a/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CodeGenerator.cs +++ b/src/libraries/System.CodeDom/src/System/CodeDom/Compiler/CodeGenerator.cs @@ -235,6 +235,11 @@ namespace System.CodeDom.Compiler protected void GenerateTypes(CodeNamespace e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + foreach (CodeTypeDeclaration c in e.Types) { if (_options.BlankLinesBetweenMembers) @@ -396,6 +401,10 @@ namespace System.CodeDom.Compiler public virtual void GenerateCodeFromMember(CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options) { + if (member == null) + { + throw new ArgumentNullException(nameof(member)); + } if (_output != null) { throw new InvalidOperationException(SR.CodeGenReentrance); @@ -704,6 +713,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateSnippetCompileUnit(CodeSnippetCompileUnit e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + GenerateDirectives(e.StartDirectives); if (e.LinePragma != null) @@ -789,6 +803,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateNamespace(CodeNamespace e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + GenerateCommentStatements(e.Comments); GenerateNamespaceStart(e); @@ -801,11 +820,23 @@ namespace System.CodeDom.Compiler protected void GenerateNamespaceImports(CodeNamespace e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + foreach (CodeNamespaceImport imp in e.Imports) { - if (imp.LinePragma != null) GenerateLinePragmaStart(imp.LinePragma); + if (imp.LinePragma != null) + { + GenerateLinePragmaStart(imp.LinePragma); + } + GenerateNamespaceImport(imp); - if (imp.LinePragma != null) GenerateLinePragmaEnd(imp.LinePragma); + if (imp.LinePragma != null) + { + GenerateLinePragmaEnd(imp.LinePragma); + } } } @@ -846,6 +877,11 @@ namespace System.CodeDom.Compiler protected void GenerateStatement(CodeStatement e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + if (e.StartDirectives.Count > 0) { GenerateDirectives(e.StartDirectives); @@ -938,6 +974,11 @@ namespace System.CodeDom.Compiler protected void GenerateStatements(CodeStatementCollection stmts) { + if (stmts == null) + { + throw new ArgumentNullException(nameof(stmts)); + } + foreach (CodeStatement stmt in stmts) { ((ICodeGenerator)this).GenerateCodeFromStatement(stmt, _output.InnerWriter, _options); @@ -946,7 +987,15 @@ namespace System.CodeDom.Compiler protected virtual void OutputAttributeDeclarations(CodeAttributeDeclarationCollection attributes) { - if (attributes.Count == 0) return; + if (attributes == null) + { + throw new ArgumentNullException(nameof(attributes)); + } + if (attributes.Count == 0) + { + return; + } + GenerateAttributeDeclarationsStart(attributes); bool first = true; foreach (CodeAttributeDeclaration current in attributes) @@ -985,6 +1034,11 @@ namespace System.CodeDom.Compiler protected virtual void OutputAttributeArgument(CodeAttributeArgument arg) { + if (arg == null) + { + throw new ArgumentNullException(nameof(arg)); + } + if (!string.IsNullOrEmpty(arg.Name)) { OutputIdentifier(arg.Name); @@ -1236,6 +1290,11 @@ namespace System.CodeDom.Compiler protected virtual void OutputParameters(CodeParameterDeclarationExpressionCollection parameters) { + if (parameters == null) + { + throw new ArgumentNullException(nameof(parameters)); + } + bool first = true; bool multiline = parameters.Count > ParameterMultilineThreshold; if (multiline) @@ -1269,6 +1328,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateBinaryOperatorExpression(CodeBinaryOperatorExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + bool indentedExpression = false; Output.Write('('); @@ -1320,6 +1384,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateParameterDeclarationExpression(CodeParameterDeclarationExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + if (e.CustomAttributes.Count > 0) { OutputAttributeDeclarations(e.CustomAttributes); @@ -1332,12 +1401,22 @@ namespace System.CodeDom.Compiler protected virtual void GenerateDirectionExpression(CodeDirectionExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + OutputDirection(e.Direction); GenerateExpression(e.Expression); } protected virtual void GeneratePrimitiveExpression(CodePrimitiveExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + if (e.Value == null) { Output.Write(NullToken); @@ -1391,7 +1470,7 @@ namespace System.CodeDom.Compiler } else { - throw new ArgumentException(SR.Format(SR.InvalidPrimitiveType, e.Value.GetType())); + throw new ArgumentException(SR.Format(SR.InvalidPrimitiveType, e.Value.GetType()), nameof(e)); } } @@ -1413,11 +1492,21 @@ namespace System.CodeDom.Compiler protected virtual void GenerateTypeReferenceExpression(CodeTypeReferenceExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + OutputType(e.Type); } protected virtual void GenerateTypeOfExpression(CodeTypeOfExpression e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + Output.Write("typeof("); OutputType(e.Type); Output.Write(')'); @@ -1428,6 +1517,10 @@ namespace System.CodeDom.Compiler protected abstract void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e); protected virtual void GenerateCommentStatement(CodeCommentStatement e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } if (e.Comment == null) { throw new ArgumentException(SR.Format(SR.Argument_NullComment, nameof(e)), nameof(e)); @@ -1437,6 +1530,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateCommentStatements(CodeCommentStatementCollection e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + foreach (CodeCommentStatement comment in e) { GenerateCommentStatement(comment); @@ -1452,7 +1550,17 @@ namespace System.CodeDom.Compiler protected abstract void GenerateRemoveEventStatement(CodeRemoveEventStatement e); protected abstract void GenerateGotoStatement(CodeGotoStatement e); protected abstract void GenerateLabeledStatement(CodeLabeledStatement e); - protected virtual void GenerateSnippetStatement(CodeSnippetStatement e) => Output.WriteLine(e.Value); + + protected virtual void GenerateSnippetStatement(CodeSnippetStatement e) + { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + + Output.WriteLine(e.Value); + } + protected abstract void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e); protected abstract void GenerateLinePragmaStart(CodeLinePragma e); protected abstract void GenerateLinePragmaEnd(CodeLinePragma e); @@ -1469,6 +1577,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateCompileUnitStart(CodeCompileUnit e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + if (e.StartDirectives.Count > 0) { GenerateDirectives(e.StartDirectives); @@ -1477,6 +1590,11 @@ namespace System.CodeDom.Compiler protected virtual void GenerateCompileUnitEnd(CodeCompileUnit e) { + if (e == null) + { + throw new ArgumentNullException(nameof(e)); + } + if (e.EndDirectives.Count > 0) { GenerateDirectives(e.EndDirectives); @@ -1495,7 +1613,7 @@ namespace System.CodeDom.Compiler { if (!IsValidIdentifier(value)) { - throw new ArgumentException(SR.Format(SR.InvalidIdentifier, value)); + throw new ArgumentException(SR.Format(SR.InvalidIdentifier, value), nameof(value)); } } diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorOptionsTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorOptionsTests.cs index 5b0eaab..e3577b1 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorOptionsTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorOptionsTests.cs @@ -27,6 +27,20 @@ namespace System.CodeDom.Compiler.Tests Assert.Equal("value", options["name"]); } + [Fact] + public void Item_GetNull_ThrowsArgumentNullException() + { + var options = new CodeGeneratorOptions(); + Assert.Throws("key", () => options[null]); + } + + [Fact] + public void Item_SetNull_ThrowsArgumentNullException() + { + var options = new CodeGeneratorOptions(); + Assert.Throws("key", () => options[null] = new object()); + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -44,24 +58,40 @@ namespace System.CodeDom.Compiler.Tests Assert.Throws(() => options.BlankLinesBetweenMembers); } + [Fact] + public void BlankLinesBetweenMembers_GetWhenNull_ReturnsTrue() + { + var options = new CodeGeneratorOptions(); + options[nameof(CodeGeneratorOptions.BlankLinesBetweenMembers)] = null; + Assert.True(options.BlankLinesBetweenMembers); + } + [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData("value")] - public void BracingStyle_Set_GetReturnsExpected(string value) + [InlineData(null, "Block")] + [InlineData("", "")] + [InlineData("value", "value")] + public void BracingStyle_Set_GetReturnsExpected(string value, string expected) { var options = new CodeGeneratorOptions { BracingStyle = value }; - Assert.Equal(value ?? "Block", options.BracingStyle); + Assert.Equal(expected, options.BracingStyle); } [Fact] - public void BracingStyle_GetWhenNotBool_ThrowsInvalidCastException() + public void BracingStyle_GetWhenNotString_ThrowsInvalidCastException() { var options = new CodeGeneratorOptions(); options[nameof(CodeGeneratorOptions.BracingStyle)] = new object(); Assert.Throws(() => options.BracingStyle); } + [Fact] + public void BracingStyle_GetWhenNull_ReturnsExpected() + { + var options = new CodeGeneratorOptions(); + options[nameof(CodeGeneratorOptions.BracingStyle)] = null; + Assert.Equal("Block", options.BracingStyle); + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -79,6 +109,14 @@ namespace System.CodeDom.Compiler.Tests Assert.Throws(() => options.ElseOnClosing); } + [Fact] + public void ElseOnClosing_GetWhenNull_Return() + { + var options = new CodeGeneratorOptions(); + options[nameof(CodeGeneratorOptions.ElseOnClosing)] = null; + Assert.False(options.ElseOnClosing); + } + [Theory] [InlineData(null)] [InlineData("")] @@ -90,13 +128,21 @@ namespace System.CodeDom.Compiler.Tests } [Fact] - public void IndentString_GetWhenNotBool_ThrowsInvalidCastException() + public void IndentString_GetWhenNotString_ThrowsInvalidCastException() { var options = new CodeGeneratorOptions(); options[nameof(CodeGeneratorOptions.IndentString)] = new object(); Assert.Throws(() => options.IndentString); } + [Fact] + public void IndentString_GetWhenNull_ReturnsExpected() + { + var options = new CodeGeneratorOptions(); + options[nameof(CodeGeneratorOptions.IndentString)] = null; + Assert.Equal(" ", options.IndentString); + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -113,5 +159,13 @@ namespace System.CodeDom.Compiler.Tests options[nameof(CodeGeneratorOptions.VerbatimOrder)] = new object(); Assert.Throws(() => options.VerbatimOrder); } + + [Fact] + public void VerbatimOrder_GetWhenNotBoolNull_ReturnsFalse() + { + var options = new CodeGeneratorOptions(); + options[nameof(CodeGeneratorOptions.VerbatimOrder)] = null; + Assert.False(options.VerbatimOrder); + } } } diff --git a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorTests.cs b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorTests.cs index d80ab31..8032f2b 100644 --- a/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorTests.cs +++ b/src/libraries/System.CodeDom/tests/System/CodeDom/Compiler/CodeGeneratorTests.cs @@ -2,8 +2,10 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; +using System.Globalization; using System.IO; using System.Reflection; using System.Text; @@ -11,319 +13,4371 @@ using Xunit; namespace System.CodeDom.Compiler.Tests { - public class CodeGeneratorTests + public class CodeGeneratorTests : CodeGenerator { - public class Generator : CodeGenerator + [Fact] + public void Ctor_Default() { - [Fact] - public void Ctor_Default() - { - Generator generator = this; - Assert.Null(generator.CurrentClass); - Assert.Null(generator.CurrentMember); - Assert.Equal("<% unknown %>", generator.CurrentMemberName); - Assert.Equal("<% unknown %>", generator.CurrentTypeName); - Assert.Throws(() => generator.Indent); - Assert.Throws(() => generator.Indent = 1); - Assert.False(generator.IsCurrentClass); - Assert.False(generator.IsCurrentDelegate); - Assert.False(generator.IsCurrentEnum); - Assert.False(generator.IsCurrentInterface); - Assert.False(generator.IsCurrentStruct); - Assert.Null(generator.Options); - Assert.Null(generator.Output); - } + CodeGeneratorTests generator = this; + Assert.Null(generator.CurrentClass); + Assert.Null(generator.CurrentMember); + Assert.Equal("<% unknown %>", generator.CurrentMemberName); + Assert.Equal("<% unknown %>", generator.CurrentTypeName); + Assert.Throws(() => generator.Indent); + Assert.False(generator.IsCurrentClass); + Assert.False(generator.IsCurrentDelegate); + Assert.False(generator.IsCurrentEnum); + Assert.False(generator.IsCurrentInterface); + Assert.False(generator.IsCurrentStruct); + Assert.Null(generator.Options); + Assert.Null(generator.Output); + } - [Fact] - public void ICodeGeneratorCreateEscapedIdentifier_Invoke_ReturnsExpected() + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("st", "st")] + public void ContinueOnNewLine_InvokeWithOutput_Appends(string st, string expected) + { + CodeGeneratorTests generator = this; + generator.PerformActionWithOutput(writer => { - ICodeGenerator generator = this; - Assert.Equal("escapedIdentifier", generator.CreateEscapedIdentifier(null)); - } + generator.ContinueOnNewLine(st); + Assert.Equal(expected + Environment.NewLine, writer.ToString()); + }); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("st")] + public void ContinueOnNewLine_InvokeWithoutOutput_ThrowsNullReferenceException(string st) + { + CodeGeneratorTests generator = this; + Assert.Throws(() => generator.ContinueOnNewLine(st)); + } - [Fact] - public void ICodeGeneratorCreateValidIdentifier_Invoke_ReturnsExpected() + [Theory] + [InlineData(-1, 0)] + [InlineData(0, 0)] + [InlineData(3, 3)] + public void Indent_SetWithOutput_GetReturnsExpected(int value, int expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - ICodeGenerator generator = this; - Assert.Equal("validIdentifier", generator.CreateValidIdentifier(null)); - } + generator.Indent = value; + Assert.Equal(expected, generator.Indent); + }); + } - protected override string NullToken => throw new NotImplementedException(); + [Fact] + public void Indent_SetWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + Assert.Throws(() => generator.Indent = 1); + } - protected override string CreateEscapedIdentifier(string value) - { - return "escapedIdentifier"; - } + public static IEnumerable GenerateBinaryOperatorExpression_TestData() + { + yield return new object[] { new CodeBinaryOperatorExpression(new CodePrimitiveExpression(1), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(2)), "(1 + 2)" }; + yield return new object[] { new CodeBinaryOperatorExpression(new CodeBinaryOperatorExpression(new CodePrimitiveExpression(1), CodeBinaryOperatorType.Multiply, new CodePrimitiveExpression(2)), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(3)), $"((1 * 2) {Environment.NewLine} + 3)" }; + yield return new object[] { new CodeBinaryOperatorExpression(new CodePrimitiveExpression(1), CodeBinaryOperatorType.Multiply, new CodeBinaryOperatorExpression(new CodePrimitiveExpression(2), CodeBinaryOperatorType.Add, new CodePrimitiveExpression(3))), $"(1 {Environment.NewLine} * (2 + 3))" }; + } - protected override string CreateValidIdentifier(string value) + [Theory] + [MemberData(nameof(GenerateBinaryOperatorExpression_TestData))] + public void GenerateBinaryOperatorExpression_Invoke_Success(CodeBinaryOperatorExpression e, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - return "validIdentifier"; - } + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateBinaryOperatorExpression(e); + Assert.Equal(expected, writer.ToString()); - protected override void GenerateArgumentReferenceExpression(CodeArgumentReferenceExpression e) - { - Output.Write("argumentReference"); - } + // Call again to make sure indent is reset. + Assert.Equal(expected, writer.ToString()); + }); + } - protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression e) - { - Output.Write("arrayCreate"); - } + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateBinaryOperatorExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateBinaryOperatorExpression(null)); + } - protected override void GenerateArrayIndexerExpression(CodeArrayIndexerExpression e) + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateBinaryOperatorExpression_NullLeftE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("arrayIndexer"); - } + var e = new CodeBinaryOperatorExpression(null, CodeBinaryOperatorType.Add, new CodePrimitiveExpression(1)); + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateBinaryOperatorExpression(null)); + }); + } - protected override void GenerateAssignStatement(CodeAssignStatement e) + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateBinaryOperatorExpression_NullRightE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("assign"); - } + var e = new CodeBinaryOperatorExpression(new CodePrimitiveExpression(1), CodeBinaryOperatorType.Add, null); + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateBinaryOperatorExpression(null)); + }); + } - protected override void GenerateAttachEventStatement(CodeAttachEventStatement e) - { - Output.Write("attachEvent"); - } + [Fact] + public void GenerateBinaryOperatorExpression_InvokeWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeBinaryOperatorExpression(); + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.GenerateBinaryOperatorExpression(e)); + } - protected override void GenerateAttributeDeclarationsEnd(CodeAttributeDeclarationCollection attributes) - { - Output.Write("attributeDeclarationsEnd"); - } + public static IEnumerable GenerateCodeFromMember_TestData() + { + yield return new object[] { new CodeTypeMember(), null, Environment.NewLine }; + yield return new object[] { new CodeTypeMember(), new CodeGeneratorOptions(), Environment.NewLine }; + yield return new object[] { new CodeTypeMember(), new CodeGeneratorOptions { BlankLinesBetweenMembers = false}, string.Empty }; + } - protected override void GenerateAttributeDeclarationsStart(CodeAttributeDeclarationCollection attributes) - { - Output.Write("attributeDeclarationsStart"); - } + [Theory] + [MemberData(nameof(GenerateCodeFromMember_TestData))] + public void GenerateCodeFromMember_Invoke_Success(CodeTypeMember member, CodeGeneratorOptions options, string expected) + { + CodeGeneratorTests generator = this; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + var writer = new StringWriter(); + generator.GenerateCodeFromMember(member, writer, options); + Assert.Equal(expected, writer.ToString()); + Assert.Null(generator.Output); + Assert.Null(generator.Options); + Assert.Null(generator.CurrentClass); + Assert.Null(generator.CurrentMember); + Assert.Equal("<% unknown %>", generator.CurrentMemberName); + Assert.Equal("<% unknown %>", generator.CurrentTypeName); + } - protected override void GenerateBaseReferenceExpression(CodeBaseReferenceExpression e) - { - Output.Write("baseReference"); - } + [Fact] + public void GenerateCodeFromMember_InvokeWithCommentsDirectivesAndLinePragma_Success() + { + CodeGeneratorTests generator = this; + var member = new CodeTypeMember { LinePragma = new CodeLinePragma() }; + member.Comments.Add(new CodeCommentStatement("Comment")); + member.Comments.Add(new CodeCommentStatement("Comment")); + member.StartDirectives.Add(new CodeDirective()); + member.StartDirectives.Add(new CodeChecksumPragma()); + member.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + member.EndDirectives.Add(new CodeDirective()); + member.EndDirectives.Add(new CodeChecksumPragma()); + member.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); - protected override void GenerateCastExpression(CodeCastExpression e) + var writer = new StringWriter(); + int generateCommentStatementsCallCount = 0; + int generateCommentCallCount = 0; + int generateLinePragmaStartCallCount = 0; + int generateDirectivesCallCount = 0; + int generateLinePragmaEndCallCount = 0; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => { - Output.Write("cast"); - } - - protected override void GenerateComment(CodeComment e) + baseMethod(actualE); + Assert.Same(member.Comments, actualE); + writer.Write("Comments "); + Assert.Equal(0, generateLinePragmaStartCallCount); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(0, generateLinePragmaEndCallCount); + generateCommentStatementsCallCount++; + }; + generator.GenerateCommentAction = (actualE) => { - Output.Write("comment"); - } - - protected override void GenerateConditionStatement(CodeConditionStatement e) + Assert.Same(member.Comments[generateCommentCallCount].Comment, actualE); + writer.Write("Comment "); + generateCommentCallCount++; + }; + generator.GenerateLinePragmaStartAction = (actualE) => { - Output.Write("condition"); - } - - protected override void GenerateConstructor(CodeConstructor e, CodeTypeDeclaration c) + Assert.Same(member.LinePragma, actualE); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaStart "); + generateLinePragmaStartCallCount++; + }; + generator.GenerateLinePragmaEndAction = (actualE) => { - Output.Write("constructor"); - } - - protected override void GenerateDelegateCreateExpression(CodeDelegateCreateExpression e) + Assert.Same(member.LinePragma, actualE); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaEnd "); + generateLinePragmaEndCallCount++; + }; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => { - Output.Write("delegateCreate"); - } + baseMethod(actualDirectives); + Assert.Same(generateDirectivesCallCount == 0 ? member.StartDirectives : member.EndDirectives, actualDirectives); + writer.Write(generateDirectivesCallCount == 0 ? "StartDirectives " : "EndDirectives"); + generateDirectivesCallCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal($"{Environment.NewLine}StartDirectives Comment Comment Comments LinePragmaStart LinePragmaEnd EndDirectives", writer.ToString()); + Assert.Equal(1, generateCommentStatementsCallCount); + Assert.Equal(2, generateCommentCallCount); + Assert.Equal(1, generateLinePragmaStartCallCount); + Assert.Equal(2, generateDirectivesCallCount); + Assert.Equal(1, generateLinePragmaEndCallCount); + } - protected override void GenerateDelegateInvokeExpression(CodeDelegateInvokeExpression e) + [Fact] + public void GenerateCodeFromMember_CodeConstructor_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeConstructor(); + int callCount = 0; + generator.GenerateConstructorAction = (actualE, type) => { - Output.Write("delegateInvoke"); - } + Assert.Same(member, actualE); + Assert.IsType(type); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateEntryPointMethod(CodeEntryPointMethod e, CodeTypeDeclaration c) + [Fact] + public void GenerateCodeFromMember_CodeEntryPointMethod_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeEntryPointMethod(); + int callCount = 0; + generator.GenerateEntryPointMethodAction = (actualE, type) => { - Output.Write("entryPointMethod"); - } + Assert.Same(member, actualE); + Assert.IsType(type); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateEvent(CodeMemberEvent e, CodeTypeDeclaration c) + [Fact] + public void GenerateCodeFromMember_CodeMemberEvent_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeMemberEvent(); + int callCount = 0; + generator.GenerateEventAction = (actualE, type) => { - Output.Write("event"); - } + Assert.Same(member, actualE); + Assert.IsType(type); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateEventReferenceExpression(CodeEventReferenceExpression e) + [Fact] + public void GenerateCodeFromMember_CodeMemberField_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeMemberField(); + int callCount = 0; + generator.GenerateFieldAction = (actualE) => { - Output.Write("eventReference"); - } + Assert.Same(member, actualE); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateExpressionStatement(CodeExpressionStatement e) + [Fact] + public void GenerateCodeFromMember_CodeMemberMethod_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeMemberMethod(); + int callCount = 0; + generator.GenerateMethodAction = (actualE, type) => { - Output.Write("expression"); - } + Assert.Same(member, actualE); + Assert.IsType(type); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateField(CodeMemberField e) + [Fact] + public void GenerateCodeFromMember_CodeMemberProperty_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeMemberProperty(); + int callCount = 0; + generator.GeneratePropertyAction = (actualE, type) => { - Output.Write("field"); - } + Assert.Same(member, actualE); + Assert.IsType(type); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateFieldReferenceExpression(CodeFieldReferenceExpression e) + [Fact] + public void GenerateCodeFromMember_CodeSnippetTypeMember_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeSnippetTypeMember(); + int callCount = 0; + generator.GenerateSnippetMemberAction = (actualE) => { - Output.Write("fieldReference"); - } + Assert.Same(member, actualE); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine + Environment.NewLine, writer.ToString()); + } - protected override void GenerateGotoStatement(CodeGotoStatement e) + [Fact] + public void GenerateCodeFromMember_CodeTypeConstructor_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var writer = new StringWriter(); + var member = new CodeTypeConstructor(); + int callCount = 0; + generator.GenerateTypeConstructorAction = (actualE) => { - Output.Write("goto"); - } + Assert.Same(member, actualE); + callCount++; + }; + generator.GenerateCodeFromMember(member, writer, null); + Assert.Equal(Environment.NewLine, writer.ToString()); + Assert.Equal(1, callCount); + } - protected override void GenerateIndexerExpression(CodeIndexerExpression e) + [Fact] + public void GenerateCodeFromMember_InvokeWithOutput_ThrowsInvalidOperationException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("indexer"); - } + Assert.Throws(() => generator.GenerateCodeFromMember(new CodeTypeMember(), new StringWriter(), new CodeGeneratorOptions())); + }); + } - protected override void GenerateIterationStatement(CodeIterationStatement e) - { - Output.Write("iteration"); - } + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCodeFromMember_NullMember_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("member", () => generator.GenerateCodeFromMember(null, new StringWriter(), new CodeGeneratorOptions())); + } - protected override void GenerateLabeledStatement(CodeLabeledStatement e) + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCodeFromMember_NullWriter_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("writer", () => generator.GenerateCodeFromMember(new CodeTypeMember(), null, new CodeGeneratorOptions())); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("text")] + public void GenerateCommentStatement_Invoke_CallsCorrectMethod(string text) + { + CodeGeneratorTests generator = this; + var e = new CodeCommentStatement(text); + int callCount = 0; + generator.GenerateCommentAction = (actualComment) => { - Output.Write("labelled"); - } + Assert.Same(e.Comment, actualComment); + callCount++; + }; + generator.GenerateCommentStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCommentStatement_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateCommentStatement(null)); + } + + [Fact] + public void GenerateCommentStatement_NullEComment_ThrowsArgumentException() + { + CodeGeneratorTests generator = this; + var e = new CodeCommentStatement(); + Assert.Throws("e", () => generator.GenerateCommentStatement(e)); + } - protected override void GenerateLinePragmaEnd(CodeLinePragma e) + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("text")] + public void GenerateCommentStatements_InvokeNonEmpty_CallsCorrectMethod(string text) + { + CodeGeneratorTests generator = this; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + var e = new CodeCommentStatementCollection(new CodeCommentStatement[] { - Output.Write("linePragmaEnd"); - } + new CodeCommentStatement(text), + new CodeCommentStatement("otherText") + }); + int callCount = 0; + generator.GenerateCommentAction = (actualComment) => + { + Assert.Same(e[callCount].Comment, actualComment); + callCount++; + }; + generator.GenerateCommentStatements(e); + Assert.Equal(2, callCount); + } - protected override void GenerateLinePragmaStart(CodeLinePragma e) + [Fact] + public void GenerateCommentStatements_InvokeEmptyE_Nop() + { + CodeGeneratorTests generator = this; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCommentStatements(new CodeCommentStatementCollection()); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCommentStatements_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateCommentStatements(null)); + } + + [Fact] + public void GenerateCommentStatements_NullValueInE_ThrowsArgumentException() + { + CodeGeneratorTests generator = this; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + var e = new CodeCommentStatementCollection(new CodeCommentStatement[] { new CodeCommentStatement() }); + Assert.Throws("e", () => generator.GenerateCommentStatements(e)); + } + + public static IEnumerable GenerateCompileUnit_TestData() + { + yield return new object[] { new CodeCompileUnit() }; + } + + [Theory] + [MemberData(nameof(GenerateCompileUnit_TestData))] + public void GenerateCompileUnit_InvokeWithOutput_Success(CodeCompileUnit e) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("linePragmaStart"); - } + generator.GenerateCompileUnitAction = (actualE, baseMethod) => baseMethod(actualE); + int generateCompileUnitStartCallCount = 0; + int generateCompileUnitEndCallCount = 0; + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(e, actualE); + Assert.Equal(0, generateCompileUnitEndCallCount); + generateCompileUnitStartCallCount++; + }; + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(e, actualE); + generateCompileUnitEndCallCount++; + }; + generator.GenerateCompileUnit(e); + Assert.Equal(1, generateCompileUnitStartCallCount); + Assert.Equal(1, generateCompileUnitEndCallCount); + Assert.Empty(writer.ToString()); + }); + } - protected override void GenerateMethod(CodeMemberMethod e, CodeTypeDeclaration c) + [Fact] + public void GenerateCompileUnit_InvokeWithDirectives_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("method"); - } + generator.GenerateCompileUnitAction = (actualE, baseMethod) => baseMethod(actualE); + + var e = new CodeSnippetCompileUnit("value") { LinePragma = new CodeLinePragma() }; + e.StartDirectives.Add(new CodeDirective()); + e.StartDirectives.Add(new CodeChecksumPragma()); + e.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + e.EndDirectives.Add(new CodeDirective()); + e.EndDirectives.Add(new CodeChecksumPragma()); + e.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + int generateCompileUnitStartCallCount = 0; + int generateCompileUnitEndCallCount = 0; + int generateDirectivesCallCount = 0; + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(e, actualE); + Assert.Equal(0, generateCompileUnitEndCallCount); + Assert.Equal(1, generateDirectivesCallCount); + generateCompileUnitStartCallCount++; + }; + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(e, actualE); + Assert.Equal(2, generateDirectivesCallCount); + generateCompileUnitEndCallCount++; + }; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => + { + Assert.Same(generateDirectivesCallCount == 0 ? e.StartDirectives : e.EndDirectives, actualDirectives); + writer.Write(generateDirectivesCallCount == 0 ? "StartDirectives " : "EndDirectives"); + generateDirectivesCallCount++; + }; + generator.GenerateCompileUnit(e); + Assert.Equal(1, generateCompileUnitStartCallCount); + Assert.Equal(1, generateCompileUnitEndCallCount); + Assert.Equal(2, generateDirectivesCallCount); + Assert.Equal("StartDirectives EndDirectives", writer.ToString()); + }); + } - protected override void GenerateMethodInvokeExpression(CodeMethodInvokeExpression e) + [Theory] + [MemberData(nameof(GenerateCompileUnit_TestData))] + public void GenerateCompileUnit_InvokeWithoutOutput_Success(CodeCompileUnit e) + { + CodeGeneratorTests generator = this; + generator.GenerateCompileUnitAction = (actualE, baseMethod) => baseMethod(actualE); + int generateCompileUnitStartCallCount = 0; + int generateCompileUnitEndCallCount = 0; + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => { - Output.Write("methodInvoke"); - } + Assert.Same(e, actualE); + Assert.Equal(0, generateCompileUnitEndCallCount); + generateCompileUnitStartCallCount++; + }; + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => + { + Assert.Same(e, actualE); + generateCompileUnitEndCallCount++; + }; + generator.GenerateCompileUnit(e); + Assert.Equal(1, generateCompileUnitStartCallCount); + Assert.Equal(1, generateCompileUnitEndCallCount); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCompileUnit_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCompileUnitAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateCompileUnit(null)); + } + + [Fact] + public void GenerateCompileUnit_NullOutputWithNamespace_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeCompileUnit(); + e.Namespaces.Add(new CodeNamespace("name")); + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCompileUnitAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.GenerateCompileUnit(e)); + } - protected override void GenerateMethodReferenceExpression(CodeMethodReferenceExpression e) + [Fact] + public void GenerateCompileUnitEnd_InvokeWithEndDirectives_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeCompileUnit(); + e.EndDirectives.Add(new CodeDirective()); + e.EndDirectives.Add(new CodeChecksumPragma()); + e.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => baseMethod(actualE); + int generateDirectivesCallCount = 0; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => { - Output.Write("methodReference"); - } + baseMethod(actualDirectives); + Assert.Same(e.EndDirectives, actualDirectives); + generateDirectivesCallCount++; + }; + generator.GenerateCompileUnitEnd(e); + Assert.Equal(1, generateDirectivesCallCount); + } - protected override void GenerateMethodReturnStatement(CodeMethodReturnStatement e) + [Fact] + public void GenerateCompileUnitEnd_InvokeWithoutEndDirectives_Nop() + { + CodeGeneratorTests generator = this; + var e = new CodeCompileUnit(); + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCompileUnitEnd(e); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCompileUnitEnd_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateCompileUnitEndAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateCompileUnitEnd(null)); + } + + [Fact] + public void GenerateCompileUnitStart_InvokeWithStartDirectives_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeCompileUnit(); + e.StartDirectives.Add(new CodeDirective()); + e.StartDirectives.Add(new CodeChecksumPragma()); + e.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => baseMethod(actualE); + int generateDirectivesCallCount = 0; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => { - Output.Write("methodReturn"); - } + baseMethod(actualDirectives); + Assert.Same(e.StartDirectives, actualDirectives); + generateDirectivesCallCount++; + }; + generator.GenerateCompileUnitStart(e); + Assert.Equal(1, generateDirectivesCallCount); + } + + [Fact] + public void GenerateCompileUnitStart_InvokeWithoutStartDirectives_Nop() + { + CodeGeneratorTests generator = this; + var e = new CodeCompileUnit(); + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCompileUnitStart(e); + } - protected override void GenerateNamespaceEnd(CodeNamespace e) + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateCompileUnitStart_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateCompileUnitStartAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateCompileUnitStart(null)); + } + + [Fact] + public void GenerateDecimalValue_Invoke_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("namespaceEnd"); - } + generator.GenerateDecimalValueAction = (actualS, baseMethod) => baseMethod(actualS); + generator.GenerateDecimalValue(decimal.MaxValue); + Assert.Equal("79228162514264337593543950335", writer.ToString()); + }); + } + + [Fact] + public void GenerateDecimalValue_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + generator.GenerateDecimalValueAction = (actualS, baseMethod) => baseMethod(actualS); + Assert.Throws(() => generator.GenerateDecimalValue(1)); + } + + public static IEnumerable GenerateDefaultValueExpression_TestData() + { + yield return new object[] { null }; + yield return new object[] { new CodeDefaultValueExpression() }; + } - protected override void GenerateNamespaceImport(CodeNamespaceImport e) + [Theory] + [MemberData(nameof(GenerateDefaultValueExpression_TestData))] + public void GenerateDefaultValueExpression_InvokeWithOutput_Nop(CodeDefaultValueExpression e) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("namespaceImport"); - } + generator.GenerateDefaultValueExpressionAction = (actualE, baseMethod) => baseMethod(e); + generator.GenerateDefaultValueExpression(e); + }); + } + + [Theory] + [MemberData(nameof(GenerateDefaultValueExpression_TestData))] + public void GenerateDefaultValueExpression_InvokeWithoutOutput_Nop(CodeDefaultValueExpression e) + { + CodeGeneratorTests generator = this; + generator.GenerateDefaultValueExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateDefaultValueExpression(e); + } + + public static IEnumerable GenerateDirectionExpression_TestData() + { + yield return new object[] { FieldDirection.In, "1" }; + yield return new object[] { FieldDirection.Out, "out 1" }; + yield return new object[] { FieldDirection.Ref, "ref 1" }; + yield return new object[] { FieldDirection.In - 1, "1" }; + yield return new object[] { FieldDirection.Ref + 1, "1" }; + } - protected override void GenerateNamespaceStart(CodeNamespace e) + [Theory] + [MemberData(nameof(GenerateDirectionExpression_TestData))] + public void GenerateDirectionExpression_Invoke_Success(FieldDirection direction, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("namespaceStart"); - } + var e = new CodeDirectionExpression(direction, new CodePrimitiveExpression(1)); + generator.GenerateDirectionExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int outputDirectionCallCount = 0; + generator.OutputDirectionAction = (actualDirection, baseMethod) => + { + baseMethod(actualDirection); + Assert.Equal(e.Direction, actualDirection); + outputDirectionCallCount++; + }; + generator.GenerateDirectionExpression(e); + Assert.Equal(expected, writer.ToString()); + Assert.Equal(1, outputDirectionCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateDirectionExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateDirectionExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + Assert.Throws("e", () => generator.GenerateDirectionExpression(null)); + } + + [Fact] + public void GenerateDirectionExpression_NullEExpression_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + var e = new CodeDirectionExpression(); + generator.GenerateDirectionExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateDirectionExpression(e)); + } + + [Theory] + [InlineData(FieldDirection.Out)] + [InlineData(FieldDirection.Ref)] + public void GenerateDirectionExpression_InvokeNonInWithoutWriter_ThrowsNullReferenceException(FieldDirection direction) + { + CodeGeneratorTests generator = this; + var e = new CodeDirectionExpression(direction, new CodePrimitiveExpression(1)); + generator.GenerateDirectionExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.GenerateDirectionExpression(e)); + } + + public static IEnumerable GenerateDirectives_TestData() + { + yield return new object[] { null }; + yield return new object[] { new CodeDirectiveCollection() }; + yield return new object[] { new CodeDirectiveCollection(new CodeDirective[] { new CodeDirective() }) }; + } - protected override void GenerateObjectCreateExpression(CodeObjectCreateExpression e) + [Theory] + [MemberData(nameof(GenerateDirectives_TestData))] + public void GenerateDirectives_InvokeWithOutput_Nop(CodeDirectiveCollection directives) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("objectCreate"); - } + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => baseMethod(actualDirectives); + generator.GenerateDirectives(directives); + }); + } + + [Theory] + [MemberData(nameof(GenerateDirectives_TestData))] + public void GenerateDirectives_InvokeWithoutOutput_Nop(CodeDirectiveCollection directives) + { + CodeGeneratorTests generator = this; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => baseMethod(actualDirectives); + generator.GenerateDirectives(directives); + } - protected override void GenerateProperty(CodeMemberProperty e, CodeTypeDeclaration c) + [Fact] + public void GenerateDoubleValue_Invoke_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => { - Output.Write("property"); - } + generator.GenerateDoubleValueAction = (actualS, baseMethod) => baseMethod(actualS); + generator.GenerateDoubleValue(double.MaxValue); + Assert.Equal("1.7976931348623157E+308", writer.ToString()); + }); + } + + [Fact] + public void GenerateDoubleValue_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + generator.GenerateDoubleValueAction = (actualS, baseMethod) => baseMethod(actualS); + Assert.Throws(() => generator.GenerateDoubleValue(1)); + } - protected override void GeneratePropertyReferenceExpression(CodePropertyReferenceExpression e) + [Fact] + public void GenerateExpression_CodeArgumentReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeArgumentReferenceExpression(); + int callCount = 0; + generator.GenerateArgumentReferenceExpressionAction = (actualE) => { - Output.Write("propertyReference"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GeneratePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e) + [Fact] + public void GenerateExpression_CodeArrayCreateExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeArrayCreateExpression(); + int callCount = 0; + generator.GenerateArrayCreateExpressionAction = (actualE) => { - Output.Write("propertySetValueReference"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateRemoveEventStatement(CodeRemoveEventStatement e) + [Fact] + public void GenerateExpression_CodeArrayIndexerExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeArrayIndexerExpression(); + int callCount = 0; + generator.GenerateArrayIndexerExpressionAction = (actualE) => { - Output.Write("removeEvent"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateSnippetExpression(CodeSnippetExpression e) + [Fact] + public void GenerateExpression_CodeBaseReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeBaseReferenceExpression(); + int callCount = 0; + generator.GenerateBaseReferenceExpressionAction = (actualE) => { - Output.Write("snippetExpression"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateSnippetMember(CodeSnippetTypeMember e) + [Fact] + public void GenerateExpression_CodeCastExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeCastExpression(); + int callCount = 0; + generator.GenerateCastExpressionAction = (actualE) => { - Output.Write("snippetMember"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateThisReferenceExpression(CodeThisReferenceExpression e) + [Fact] + public void GenerateExpression_CodeDefaultValueExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeDefaultValueExpression(); + int callCount = 0; + generator.GenerateDefaultValueExpressionAction = (actualE, baseMethod) => { - Output.Write("thisReference"); - } + baseMethod(actualE); + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e) + [Fact] + public void GenerateExpression_CodeDelegateCreateExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeDelegateCreateExpression(); + int callCount = 0; + generator.GenerateDelegateCreateExpressionAction = (actualE) => { - Output.Write("throwException"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e) + [Fact] + public void GenerateExpression_CodeDelegateInvokeExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeDelegateInvokeExpression(); + int callCount = 0; + generator.GenerateDelegateInvokeExpressionAction = (actualE) => { - Output.Write("tryCatchFinally"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateTypeConstructor(CodeTypeConstructor e) + [Fact] + public void GenerateExpression_CodeDirectionExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeDirectionExpression(); + int callCount = 0; + generator.GenerateDirectionExpressionAction = (actualE, baseMethod) => { - Output.Write("typeConstructor"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateTypeEnd(CodeTypeDeclaration e) + [Fact] + public void GenerateExpression_CodeEventReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeEventReferenceExpression(); + int callCount = 0; + generator.GenerateEventReferenceExpressionAction = (actualE) => { - Output.Write("typeEnd"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateTypeStart(CodeTypeDeclaration e) + [Fact] + public void GenerateExpression_CodeFieldReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeFieldReferenceExpression(); + int callCount = 0; + generator.GenerateFieldReferenceExpressionAction = (actualE) => { - Output.Write("typeStart"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e) + [Fact] + public void GenerateExpression_CodeIndexerExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeIndexerExpression(); + int callCount = 0; + generator.GenerateIndexerExpressionAction = (actualE) => { - Output.Write("variableDeclarationStatement"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void GenerateVariableReferenceExpression(CodeVariableReferenceExpression e) + [Fact] + public void GenerateExpression_CodeMethodInvokeExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeMethodInvokeExpression(); + int callCount = 0; + generator.GenerateMethodInvokeExpressionAction = (actualE) => { - Output.Write("variableReferenceExpression"); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override string GetTypeOutput(CodeTypeReference value) + [Fact] + public void GenerateExpression_CodeMethodReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeMethodReferenceExpression(); + int callCount = 0; + generator.GenerateMethodReferenceExpressionAction = (actualE) => { - throw new NotImplementedException(); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override bool IsValidIdentifier(string value) + [Fact] + public void GenerateExpression_CodeObjectCreateExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeObjectCreateExpression(); + int callCount = 0; + generator.GenerateObjectCreateExpressionAction = (actualE) => { - return value == "invalid"; - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override void OutputType(CodeTypeReference typeRef) + [Fact] + public void GenerateExpression_CodeParameterDeclarationExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeParameterDeclarationExpression(); + int callCount = 0; + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => { - throw new NotImplementedException(); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override string QuoteSnippetString(string value) + [Fact] + public void GenerateExpression_CodePrimitiveExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression(); + int callCount = 0; + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => { - throw new NotImplementedException(); - } + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } - protected override bool Supports(GeneratorSupport support) + [Fact] + public void GenerateExpression_CodePropertyReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodePropertyReferenceExpression(); + int callCount = 0; + generator.GeneratePropertyReferenceExpressionAction = (actualE) => { - throw new NotImplementedException(); + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateExpression_CodePropertySetValueReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodePropertySetValueReferenceExpression(); + int callCount = 0; + generator.GeneratePropertySetValueReferenceExpressionAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateExpression_CodeSnippetExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeSnippetExpression(); + int callCount = 0; + generator.GenerateSnippetExpressionAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateExpression_CodeThisReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeThisReferenceExpression(); + int callCount = 0; + generator.GenerateThisReferenceExpressionAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateExpression_CodeTypeOfExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeTypeOfExpression(); + int callCount = 0; + generator.GenerateTypeOfExpressionAction = (actualE, baseMethod) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateExpression_CodeTypeReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeTypeReferenceExpression(); + int callCount = 0; + generator.GenerateTypeReferenceExpressionAction = (actualE, baseMethod) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateVariableReferenceExpression_CodeVariableReferenceExpression_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeVariableReferenceExpression(); + int callCount = 0; + generator.GenerateVariableReferenceExpressionAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateExpression(e); + Assert.Equal(1, callCount); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateExpression(null)); + } + + public static IEnumerable GenerateExpression_InvalidE_TestData() + { + yield return new object[] { new CodeExpression() }; + yield return new object[] { new CustomCodeExpression() }; + } + + [Theory] + [MemberData(nameof(GenerateExpression_InvalidE_TestData))] + public void GenerateExpression_InvalidE_ThrowsArgumentException(CodeExpression e) + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateExpression(e)); + } + + [Fact] + public void GenerateNamespace_InvokeEmpty_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + int generateNamespaceStartCallCount = 0; + int generateNamespaceEndCallCount = 0; + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateNamespaceStartAction = (actualE) => + { + Assert.Same(e, actualE); + Assert.Equal(0, generateNamespaceEndCallCount); + writer.Write("NamespaceStart "); + generateNamespaceStartCallCount++; + }; + generator.GenerateNamespaceEndAction = (actualE) => + { + Assert.Same(e, actualE); + writer.Write("NamespaceEnd"); + generateNamespaceEndCallCount++; + }; + + generator.GenerateNamespace(e); + Assert.Equal(1, generateNamespaceStartCallCount); + Assert.Equal(1, generateNamespaceEndCallCount); + Assert.Equal($"NamespaceStart {Environment.NewLine}NamespaceEnd", writer.ToString()); + }); + } + + [Fact] + public void GenerateNamespace_InvokeWithComments_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Comments.Add(new CodeCommentStatement("Comment")); + e.Comments.Add(new CodeCommentStatement("Comment")); + int generateCommentStatementsCallCount = 0; + int generateCommentCallCount = 0; + int generateNamespaceStartCallCount = 0; + int generateNamespaceEndCallCount = 0; + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(e.Comments, actualE); + Assert.Equal(0, generateNamespaceStartCallCount); + Assert.Equal(0, generateNamespaceEndCallCount); + writer.Write("Comments "); + generateCommentStatementsCallCount++; + }; + generator.GenerateCommentAction = (actualE) => + { + Assert.Same(e.Comments[generateCommentCallCount].Comment, actualE); + writer.Write("Comment "); + generateCommentCallCount++; + }; + generator.GenerateNamespaceStartAction = (actualE) => + { + Assert.Same(e, actualE); + Assert.Equal(0, generateNamespaceEndCallCount); + writer.Write("NamespaceStart "); + generateNamespaceStartCallCount++; + }; + generator.GenerateNamespaceEndAction = (actualE) => + { + Assert.Same(e, actualE); + writer.Write("NamespaceEnd"); + generateNamespaceEndCallCount++; + }; + + generator.GenerateNamespace(e); + Assert.Equal(1, generateCommentStatementsCallCount); + Assert.Equal(2, generateCommentCallCount); + Assert.Equal(1, generateNamespaceStartCallCount); + Assert.Equal(1, generateNamespaceEndCallCount); + Assert.Equal($"Comment Comment Comments NamespaceStart {Environment.NewLine}NamespaceEnd", writer.ToString()); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateNamespace_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateNamespace(null)); + } + + [Fact] + public void GenerateNamespace_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeNamespace(); + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateNamespaceStartAction = (actualE) => {}; + generator.GenerateNamespaceEndAction = (actualE) => {}; + + Assert.Throws(() => generator.GenerateNamespace(e)); + } + + [Fact] + public void GenerateNamespace_NullValueInE_ThrowsArgumentException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Comments.Add(new CodeCommentStatement()); + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateNamespaceStartAction = (actualE) => {}; + generator.GenerateNamespaceEndAction = (actualE) => {}; + + Assert.Throws("e", () => generator.GenerateNamespace(e)); + }); + } + + [Fact] + public void GenerateNamespaceImports_InvokeEmptyWithOutput_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + int generateNamespaceCallCount = 0; + generator.GenerateNamespaceImportAction = (actualE) => generateNamespaceCallCount++; + generator.GenerateNamespaceImports(e); + Assert.Equal(0, generateNamespaceCallCount); + Assert.Empty(writer.ToString()); + }); + } + + [Fact] + public void GenerateNamespaceImports_InvokeNonEmptyWithOutput_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Imports.Add(new CodeNamespaceImport("Namespace1")); + e.Imports.Add(new CodeNamespaceImport("Namespace2")); + int generateNamespaceCallCount = 0; + generator.GenerateNamespaceImportAction = (actualE) => + { + Assert.Same(e.Imports[generateNamespaceCallCount], actualE); + generateNamespaceCallCount++; + }; + generator.GenerateNamespaceImports(e); + Assert.Equal(2, generateNamespaceCallCount); + Assert.Empty(writer.ToString()); + }); + } + + [Fact] + public void GenerateNamespaceImports_InvokeWithOutputWithLinePragma_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Imports.Add(new CodeNamespaceImport("Namespace1") { LinePragma = new CodeLinePragma() }); + e.Imports.Add(new CodeNamespaceImport("Namespace2") { LinePragma = new CodeLinePragma() }); + int generateLinePragmaStartCallCount = 0; + int generateNamespaceCallCount = 0; + int generateLinePragmaEndCallCount = 0; + generator.GenerateLinePragmaStartAction = (actualE) => + { + Assert.Same(e.Imports[generateLinePragmaEndCallCount].LinePragma, actualE); + Assert.Equal(generateLinePragmaStartCallCount, generateNamespaceCallCount); + Assert.Equal(generateLinePragmaStartCallCount, generateLinePragmaEndCallCount); + writer.Write("LinePragmaStart "); + generateLinePragmaStartCallCount++; + }; + generator.GenerateNamespaceImportAction = (actualE) => + { + Assert.Same(e.Imports[generateLinePragmaEndCallCount], actualE); + Assert.Equal(generateNamespaceCallCount, generateLinePragmaEndCallCount); + writer.Write("Namespace "); + generateNamespaceCallCount++; + }; + generator.GenerateLinePragmaEndAction = (actualE) => + { + Assert.Same(e.Imports[generateLinePragmaEndCallCount].LinePragma, actualE); + writer.Write("LinePragmaEnd"); + generateLinePragmaEndCallCount++; + }; + generator.GenerateNamespaceImports(e); + Assert.Equal(2, generateLinePragmaStartCallCount); + Assert.Equal(2, generateNamespaceCallCount); + Assert.Equal(2, generateLinePragmaEndCallCount); + Assert.Equal("LinePragmaStart Namespace LinePragmaEndLinePragmaStart Namespace LinePragmaEnd", writer.ToString()); + }); + } + + [Fact] + public void GenerateNamespaceImports_InvokeEmptyWithoutOutput_Success() + { + CodeGeneratorTests generator = this; + var e = new CodeNamespace(); + int generateNamespaceCallCount = 0; + generator.GenerateNamespaceImportAction = (actualE) => generateNamespaceCallCount++; + generator.GenerateNamespaceImports(e); + Assert.Equal(0, generateNamespaceCallCount); + } + + [Fact] + public void GenerateNamespaceImports_InvokeWithoutOutput_Success() + { + CodeGeneratorTests generator = this; + var e = new CodeNamespace(); + e.Imports.Add(new CodeNamespaceImport("Namespace1")); + e.Imports.Add(new CodeNamespaceImport("Namespace2")); + int generateNamespaceCallCount = 0; + generator.GenerateNamespaceImportAction = (actualE) => + { + Assert.Same(e.Imports[generateNamespaceCallCount], actualE); + generateNamespaceCallCount++; + }; + generator.GenerateNamespaceImports(e); + Assert.Equal(2, generateNamespaceCallCount); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateNamespaceImports_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateNamespaceImports(null)); + } + + public static IEnumerable GenerateParameterDeclarationExpression_TestData() + { + yield return new object[] { null, null, FieldDirection.In, "Type " }; + yield return new object[] { string.Empty, string.Empty, FieldDirection.In, "Type " }; + yield return new object[] { "type", "name", FieldDirection.In, "Type name" }; + yield return new object[] { null, null, FieldDirection.Out, "out Type " }; + yield return new object[] { string.Empty, string.Empty, FieldDirection.Out, "out Type " }; + yield return new object[] { "type", "name", FieldDirection.Out, "out Type name" }; + yield return new object[] { null, null, FieldDirection.Ref, "ref Type " }; + yield return new object[] { string.Empty, string.Empty, FieldDirection.Ref, "ref Type " }; + yield return new object[] { "type", "name", FieldDirection.Ref, "ref Type name" }; + yield return new object[] { null, null, FieldDirection.In - 1, "Type " }; + yield return new object[] { string.Empty, string.Empty, FieldDirection.In - 1, "Type " }; + yield return new object[] { "type", "name", FieldDirection.In - 1, "Type name" }; + yield return new object[] { null, null, FieldDirection.Ref + 1, "Type " }; + yield return new object[] { string.Empty, string.Empty, FieldDirection.Ref + 1, "Type " }; + yield return new object[] { "type", "name", FieldDirection.Ref + 1, "Type name" }; + } + + [Theory] + [MemberData(nameof(GenerateParameterDeclarationExpression_TestData))] + public void GenerateParameterDeclarationExpression_Invoke_Success(string type, string name, FieldDirection direction, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeParameterDeclarationExpression(type, name) { Direction = direction }; + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int outputDirectionCallCount = 0; + int outputTypeNamePairCallCount = 0; + int outputTypeCallCount = 0; + generator.OutputDirectionAction = (actualDirection, baseMethod) => + { + baseMethod(actualDirection); + Assert.Equal(e.Direction, actualDirection); + Assert.Equal(0, outputTypeNamePairCallCount); + Assert.Equal(0, outputTypeCallCount); + outputDirectionCallCount++; + }; + generator.OutputTypeNamePairAction = (actualType, actualName, baseMethod) => + { + baseMethod(actualType, actualName); + Assert.Same(e.Type, actualType); + Assert.Same(e.Name, actualName); + outputTypeNamePairCallCount++; + }; + generator.OutputTypeAction = (actualType) => + { + Assert.Same(e.Type, actualType); + writer.Write("Type"); + outputTypeCallCount++; + }; + generator.OutputIdentifierAction = (actualIdent, baseMethod) => baseMethod(actualIdent); + generator.GenerateParameterDeclarationExpression(e); + Assert.Equal(expected, writer.ToString()); + Assert.Equal(1, outputDirectionCallCount); + Assert.Equal(1, outputTypeNamePairCallCount); + Assert.Equal(1, outputTypeCallCount); + }); + } + + [Fact] + public void GenerateParameterDeclarationExpression_InvokeWithCustomAttributes_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeParameterDeclarationExpression("Type", "Name") { Direction = FieldDirection.Ref }; + e.CustomAttributes.Add(new CodeAttributeDeclaration("name")); + e.CustomAttributes.Add(new CodeAttributeDeclaration("name")); + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int outputAttributeDeclarationsCallCount = 0; + int outputDirectionCallCount = 0; + int outputTypeNamePairCallCount = 0; + int outputTypeCallCount = 0; + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => + { + baseMethod(actualAttributes); + Assert.Same(e.CustomAttributes, actualAttributes); + Assert.Equal(0, outputDirectionCallCount); + Assert.Equal(0, outputTypeNamePairCallCount); + Assert.Equal(0, outputTypeCallCount); + outputAttributeDeclarationsCallCount++; + }; + generator.GenerateAttributeDeclarationsStartAction = (actualArg) => writer.Write("StartAttributes "); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GenerateAttributeDeclarationsEndAction = (actualArg) => writer.Write(" EndAttributes"); + generator.OutputDirectionAction = (actualDirection, baseMethod) => + { + baseMethod(actualDirection); + Assert.Equal(e.Direction, actualDirection); + Assert.Equal(0, outputTypeNamePairCallCount); + Assert.Equal(0, outputTypeCallCount); + outputDirectionCallCount++; + }; + generator.OutputTypeNamePairAction = (actualType, actualName, baseMethod) => + { + baseMethod(actualType, actualName); + Assert.Same(e.Type, actualType); + Assert.Same(e.Name, actualName); + outputTypeNamePairCallCount++; + }; + generator.OutputTypeAction = (actualType) => + { + Assert.Same(e.Type, actualType); + writer.Write("Type"); + outputTypeCallCount++; + }; + generator.OutputIdentifierAction = (actualIdent, baseMethod) => baseMethod(actualIdent); + generator.GenerateParameterDeclarationExpression(e); + Assert.Equal($"StartAttributes name(), {Environment.NewLine}name() EndAttributes ref Type Name", writer.ToString()); + Assert.Equal(1, outputAttributeDeclarationsCallCount); + Assert.Equal(1, outputDirectionCallCount); + Assert.Equal(1, outputTypeNamePairCallCount); + Assert.Equal(1, outputTypeCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateParameterDeclarationExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateParameterDeclarationExpression(null)); + } + + [Fact] + public void GenerateParameterDeclarationExpression_InvokeWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeParameterDeclarationExpression(); + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.OutputTypeNamePairAction = (actualType, actualName, baseMethod) => baseMethod(actualType, actualName); + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.OutputTypeAction = (actualType) => { }; + Assert.Throws(() => generator.GenerateParameterDeclarationExpression(e)); + } + + public static IEnumerable GeneratePrimitiveExpression_TestData() + { + yield return new object[] { null, "NullToken" }; + yield return new object[] { 'a', "'a'" }; + yield return new object[] { (short)1, "1" }; + yield return new object[] { 1, "1" }; + yield return new object[] { (long)1, "1" }; + yield return new object[] { (byte)1, "1" }; + yield return new object[] { true, "true" }; + yield return new object[] { false, "false" }; + } + + [Theory] + [MemberData(nameof(GeneratePrimitiveExpression_TestData))] + public void GeneratePrimitiveExpression_Invoke_Success(object value, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodePrimitiveExpression(value); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GeneratePrimitiveExpression(e); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Fact] + public void GeneratePrimitiveExpression_InvokeFloat_Success() + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression((float)1); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int generateSingleFloatValueCallCount = 0; + generator.GenerateSingleFloatValueAction = (actualValue, baseMethod) => + { + Assert.Equal((float)1, actualValue); + generateSingleFloatValueCallCount++; + }; + generator.GeneratePrimitiveExpression(e); + Assert.Equal(1, generateSingleFloatValueCallCount); + } + + [Fact] + public void GeneratePrimitiveExpression_InvokeDouble_Success() + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression((double)1); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int generateDoubleValueCallCount = 0; + generator.GenerateDoubleValueAction = (actualValue, baseMethod) => + { + Assert.Equal((double)1, actualValue); + generateDoubleValueCallCount++; + }; + generator.GeneratePrimitiveExpression(e); + Assert.Equal(1, generateDoubleValueCallCount); + } + + [Fact] + public void GeneratePrimitiveExpression_InvokeDecimal_Success() + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression((decimal)1); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int generateDecimalValueCallCount = 0; + generator.GenerateDecimalValueAction = (actualValue, baseMethod) => + { + Assert.Equal((decimal)1, actualValue); + generateDecimalValueCallCount++; + }; + generator.GeneratePrimitiveExpression(e); + Assert.Equal(1, generateDecimalValueCallCount); + } + + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("result", "result")] + public void GeneratePrimitiveExpression_InvokeString_Success(string result, string expected) + { + CodeGeneratorTests generator = this; + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + PerformActionWithOutput(writer => + { + var e = new CodePrimitiveExpression("value"); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int quoteSnippetCallCount = 0; + generator.QuoteSnippetStringAction = (actualValue) => + { + Assert.Equal("value", actualValue); + quoteSnippetCallCount++; + return result; + }; + generator.GeneratePrimitiveExpression(e); + Assert.Equal(expected, writer.ToString()); + Assert.Equal(1, quoteSnippetCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GeneratePrimitiveExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GeneratePrimitiveExpression(null)); + } + + public static IEnumerable GeneratePrimitiveExpression_InvalidEValue_TestData() + { + yield return new object[] { new object() }; + yield return new object[] { DBNull.Value }; + yield return new object[] { new DateTime() }; + yield return new object[] { (sbyte)1 }; + yield return new object[] { (ushort)1 }; + yield return new object[] { (uint)1 }; + yield return new object[] { (ulong)1 }; + } + + [Theory] + [MemberData(nameof(GeneratePrimitiveExpression_InvalidEValue_TestData))] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GeneratePrimitiveExpression_InvalidE_ThrowsArgumentException(object value) + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression(value); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GeneratePrimitiveExpression(e)); + } + + public static IEnumerable GeneratePrimitiveExpression_WithoutOutput_TestData() + { + yield return new object[] { null }; + yield return new object[] { "" }; + yield return new object[] { "value" }; + yield return new object[] { 'a' }; + yield return new object[] { (short)1 }; + yield return new object[] { 1 }; + yield return new object[] { (long)1 }; + yield return new object[] { (byte)1 }; + yield return new object[] { (float)1 }; + yield return new object[] { (double)1 }; + yield return new object[] { (decimal)1 }; + yield return new object[] { true }; + yield return new object[] { false }; + } + + [Theory] + [MemberData(nameof(GeneratePrimitiveExpression_WithoutOutput_TestData))] + public void GeneratePrimitiveExpression_InvokeWithoutOutput_ThrowsNullRefereneException(object value) + { + CodeGeneratorTests generator = this; + var e = new CodePrimitiveExpression(value); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateSingleFloatValueAction = (actualS, baseMethod) => baseMethod(actualS); + generator.GenerateDoubleValueAction = (actualD, baseMethod) => baseMethod(actualD); + generator.GenerateDecimalValueAction = (actualD, baseMethod) => baseMethod(actualD); + generator.QuoteSnippetStringAction = (actualValue) => actualValue; + Assert.Throws(() => generator.GeneratePrimitiveExpression(e)); + } + + [Fact] + public void GenerateSingleFloatValue_Invoke_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.GenerateSingleFloatValueAction = (actualS, baseMethod) => baseMethod(actualS); + generator.GenerateSingleFloatValue(float.MaxValue); + Assert.Equal(float.MaxValue.ToString("R", CultureInfo.InvariantCulture.NumberFormat), writer.ToString()); + }); + } + + [Fact] + public void GenerateSingleFloatValue_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + generator.GenerateSingleFloatValueAction = (actualS, baseMethod) => baseMethod(actualS); + Assert.Throws(() => generator.GenerateSingleFloatValue(1)); + } + + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("value", "value")] + public void GenerateSnippetCompileUnit_Invoke_Success(string value, string expected) + { + CodeGeneratorTests generator = this; + var e = new CodeSnippetCompileUnit(value); + PerformActionWithOutput(writer => + { + generator.GenerateSnippetCompileUnit(e); + Assert.Equal(expected + Environment.NewLine, writer.ToString()); + }); + } + + [Fact] + public void GenerateSnippetCompileUnit_InvokeWithDirectivesAndLinePragma_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeSnippetCompileUnit("value") { LinePragma = new CodeLinePragma() }; + e.StartDirectives.Add(new CodeDirective()); + e.StartDirectives.Add(new CodeChecksumPragma()); + e.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + e.EndDirectives.Add(new CodeDirective()); + e.EndDirectives.Add(new CodeChecksumPragma()); + e.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + + int generateLinePragmaStartCallCount = 0; + int generateDirectivesCallCount = 0; + int generateLinePragmaEndCallCount = 0; + generator.GenerateLinePragmaStartAction = (actualE) => + { + Assert.Same(e.LinePragma, actualE); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaStart "); + generateLinePragmaStartCallCount++; + }; + generator.GenerateLinePragmaEndAction = (actualE) => + { + Assert.Same(e.LinePragma, actualE); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaEnd "); + generateLinePragmaEndCallCount++; + }; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => + { + baseMethod(actualDirectives); + Assert.Same(generateDirectivesCallCount == 0 ? e.StartDirectives : e.EndDirectives, actualDirectives); + writer.Write(generateDirectivesCallCount == 0 ? "StartDirectives " : "EndDirectives"); + generateDirectivesCallCount++; + }; + generator.GenerateSnippetCompileUnit(e); + Assert.Equal($"StartDirectives LinePragmaStart value{Environment.NewLine}LinePragmaEnd EndDirectives", writer.ToString()); + Assert.Equal(1, generateLinePragmaStartCallCount); + Assert.Equal(2, generateDirectivesCallCount); + Assert.Equal(1, generateLinePragmaEndCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateSnippetCompileUnit_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateSnippetCompileUnit(null)); + } + + [Fact] + public void GenerateSnippetCompileUnit_InvokeWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeSnippetCompileUnit(); + Assert.Throws(() => generator.GenerateSnippetCompileUnit(e)); + } + + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("value", "value")] + public void GenerateSnippetStatement_Invoke_Success(string value, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.GenerateSnippetStatementAction = (actualE, baseMethod) => baseMethod(actualE); + var e = new CodeSnippetStatement(value); + generator.GenerateSnippetStatement(e); + Assert.Equal(expected + Environment.NewLine, writer.ToString()); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateSnippetStatement_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateSnippetStatementAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateSnippetStatement(null)); + } + + [Fact] + public void GenerateStatement_InvokeWithDirectivesAndLinePragma_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeGotoStatement { LinePragma = new CodeLinePragma() }; + e.StartDirectives.Add(new CodeDirective()); + e.StartDirectives.Add(new CodeChecksumPragma()); + e.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + e.EndDirectives.Add(new CodeDirective()); + e.EndDirectives.Add(new CodeChecksumPragma()); + e.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + + int generateLinePragmaStartCallCount = 0; + int generateDirectivesCallCount = 0; + int generateStatementCallCount = 0; + int generateLinePragmaEndCallCount = 0; + generator.GenerateLinePragmaStartAction = (actualE) => + { + Assert.Same(e.LinePragma, actualE); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(0, generateStatementCallCount); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaStart "); + generateLinePragmaStartCallCount++; + }; + generator.GenerateGotoStatementAction = (actualE) => + { + Assert.Same(e, actualE); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("Statement "); + generateStatementCallCount++; + }; + generator.GenerateLinePragmaEndAction = (actualE) => + { + Assert.Same(e.LinePragma, actualE); + Assert.Equal(1, generateDirectivesCallCount); + writer.Write("LinePragmaEnd "); + generateLinePragmaEndCallCount++; + }; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => + { + baseMethod(actualDirectives); + Assert.Same(generateDirectivesCallCount == 0 ? e.StartDirectives : e.EndDirectives, actualDirectives); + writer.Write(generateDirectivesCallCount == 0 ? "StartDirectives " : "EndDirectives"); + generateDirectivesCallCount++; + }; + generator.GenerateStatement(e); + Assert.Equal($"StartDirectives LinePragmaStart Statement LinePragmaEnd EndDirectives", writer.ToString()); + Assert.Equal(1, generateLinePragmaStartCallCount); + Assert.Equal(1, generateStatementCallCount); + Assert.Equal(2, generateDirectivesCallCount); + Assert.Equal(1, generateLinePragmaEndCallCount); + }); + } + + [Fact] + public void GenerateStatement_CodeAssignStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeAssignStatement(); + int callCount = 0; + generator.GenerateAssignStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeAttachEventStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeAttachEventStatement(); + int callCount = 0; + generator.GenerateAttachEventStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeConditionStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeConditionStatement(); + int callCount = 0; + generator.GenerateConditionStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeExpressionStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeExpressionStatement(); + int callCount = 0; + generator.GenerateExpressionStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeGotoStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeGotoStatement(); + int callCount = 0; + generator.GenerateGotoStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeIterationStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeIterationStatement(); + int callCount = 0; + generator.GenerateIterationStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeLabeledStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeLabeledStatement(); + int callCount = 0; + generator.GenerateLabeledStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeMethodReturnStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeMethodReturnStatement(); + int callCount = 0; + generator.GenerateMethodReturnStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeRemoveEventStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeRemoveEventStatement(); + int callCount = 0; + generator.GenerateRemoveEventStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeSnippetStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.Indent = 1; + + var e = new CodeSnippetStatement(); + int callCount = 0; + generator.GenerateSnippetStatementAction = (actualE, baseMethod) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + + Assert.Equal(1, generator.Indent); + }); + } + + [Fact] + public void GenerateStatement_CodeThrowExpressionStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeThrowExceptionStatement(); + int callCount = 0; + generator.GenerateThrowExceptionStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeTryCatchFinallyStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeTryCatchFinallyStatement(); + int callCount = 0; + generator.GenerateTryCatchFinallyStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + public void GenerateStatement_CodeVariableDeclarationStatement_CallsCorrectMethod() + { + CodeGeneratorTests generator = this; + var e = new CodeVariableDeclarationStatement(); + int callCount = 0; + generator.GenerateVariableDeclarationStatementAction = (actualE) => + { + Assert.Same(e, actualE); + callCount++; + }; + generator.GenerateStatement(e); + Assert.Equal(1, callCount); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateStatement_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateStatement(null)); + } + + public static IEnumerable GenerateStatement_InvalidE_TestData() + { + yield return new object[] { new CodeStatement() }; + yield return new object[] { new CustomCodeStatement() }; + } + + [Theory] + [MemberData(nameof(GenerateStatement_InvalidE_TestData))] + public void GenerateStatement_InvalidE_ThrowsArgumentException(CodeStatement e) + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateStatement(e)); + } + + [Fact] + public void GenerateStatement_CodeSnippetStatementWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeSnippetStatement(); + generator.GenerateSnippetStatementAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.GenerateStatement(e)); + } + + [Fact] + public void GenerateStatements_InvokeWithWriter_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var stmts = new CodeStatementCollection(new CodeStatement[] { new CodeGotoStatement(), new CodeGotoStatement() }); + int generateStatementCallCount = 0; + generator.GenerateGotoStatementAction = (actualE) => + { + Assert.Same(stmts[generateStatementCallCount], actualE); + generateStatementCallCount++; + }; + generator.GenerateStatements(stmts); + Assert.Equal(2, generateStatementCallCount); + }); + } + + [Fact] + public void GenerateStatements_InvokeEmptyStatementsWithWriter_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var stmts = new CodeStatementCollection(); + generator.GenerateStatements(stmts); + Assert.Empty(writer.ToString()); + }); + } + + [Fact] + public void GenerateStatements_InvokeEmptyStatementsWithoutWriter_Nop() + { + CodeGeneratorTests generator = this; + var stmts = new CodeStatementCollection(); + generator.GenerateStatements(stmts); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateStatements_NullStmts_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("stmts", () => generator.GenerateStatements(null)); + } + + [Fact] + public void GenerateStatements_InvalidStatementInStmts_ThrowsArgumentException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var stmts = new CodeStatementCollection(new CodeStatement[] { new CodeStatement() }); + Assert.Throws("e", () => generator.GenerateStatements(stmts)); + }); + } + + [Fact] + public void GenerateStatements_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var stmts = new CodeStatementCollection(new CodeStatement[] { new CodeStatement() }); + Assert.Throws(() => generator.GenerateStatements(stmts)); + } + + [Fact] + public void GenerateTypeOfExpression_Invoke_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeTypeOfExpression(new CodeTypeReference()); + generator.GenerateTypeOfExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int outputTypeCallCount = 0; + generator.OutputTypeAction = (actualTypeRef) => + { + Assert.Same(e.Type, actualTypeRef); + writer.Write("Type"); + outputTypeCallCount++; + }; + generator.GenerateTypeOfExpression(e); + Assert.Equal("typeof(Type)", writer.ToString()); + Assert.Equal(1, outputTypeCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateTypeOfExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateTypeOfExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateTypeOfExpression(null)); + } + + [Fact] + public void GenerateTypeOfExpression_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var e = new CodeTypeOfExpression(); + generator.GenerateTypeOfExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.GenerateTypeOfExpression(e)); + } + + [Fact] + public void GenerateTypeReferenceExpression_Invoke_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeTypeReferenceExpression(new CodeTypeReference()); + generator.GenerateTypeReferenceExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + int outputTypeCallCount = 0; + generator.OutputTypeAction = (actualTypeRef) => + { + Assert.Same(e.Type, actualTypeRef); + writer.Write("Type"); + outputTypeCallCount++; + }; + generator.GenerateTypeReferenceExpression(e); + Assert.Equal("Type", writer.ToString()); + Assert.Equal(1, outputTypeCallCount); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateTypeReferenceExpression_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.GenerateTypeReferenceExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.GenerateTypeReferenceExpression(null)); + } + + public static IEnumerable GenerateTypes_TestData() + { + yield return new object[] { new CodeTypeDeclaration(), null, $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + yield return new object[] { new CodeTypeDeclaration(), new CodeGeneratorOptions(), $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + yield return new object[] { new CodeTypeDeclaration(), new CodeGeneratorOptions { BlankLinesBetweenMembers = false }, $"TypeStart TypeEndTypeStart TypeEnd" }; + + yield return new object[] { new CodeTypeDeclaration("name") { IsClass = true }, null, $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + yield return new object[] { new CodeTypeDeclaration("name") { IsEnum = true }, null, $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + yield return new object[] { new CodeTypeDeclaration("name") { IsInterface = true }, null, $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + yield return new object[] { new CodeTypeDeclaration("name") { IsStruct = true }, null, $"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd" }; + } + + [Theory] + [MemberData(nameof(GenerateTypes_TestData))] + public void GenerateTypes_InvokeClassWithWriter_Success(CodeTypeDeclaration type, CodeGeneratorOptions options, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Types.Add(new CodeTypeDeclaration()); + e.Types.Add(type); + int generateTypeStartCallCount = 0; + int generateTypeEndCallCount = 0; + generator.GenerateTypeStartAction = (actualE) => + { + Assert.Same(e.Types[generateTypeStartCallCount], actualE); + Assert.Equal(generateTypeStartCallCount, generateTypeEndCallCount); + writer.Write("TypeStart "); + generateTypeStartCallCount++; + }; + generator.GenerateTypeEndAction = (actualE) => + { + Assert.Same(e.Types[generateTypeEndCallCount], actualE); + writer.Write("TypeEnd"); + generateTypeEndCallCount++; + }; + generator.GenerateTypes(e); + Assert.Equal(expected, writer.ToString()); + Assert.Equal(2, generateTypeStartCallCount); + Assert.Equal(2, generateTypeEndCallCount); + + Assert.Same(e.Types[1], generator.CurrentClass); + Assert.Null(generator.CurrentMember); + Assert.Equal("<% unknown %>", generator.CurrentMemberName); + Assert.Same(e.Types[1].Name, generator.CurrentTypeName); + Assert.Equal(e.Types[1].IsClass, generator.IsCurrentClass); + Assert.False(generator.IsCurrentDelegate); + Assert.Equal(e.Types[1].IsEnum, generator.IsCurrentEnum); + Assert.Equal(e.Types[1].IsInterface, generator.IsCurrentInterface); + Assert.Equal(e.Types[1].IsStruct, generator.IsCurrentStruct); + }, options); + } + + [Fact] + public void GenerateTypes_InvokeDelegateWithWriter_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + e.Types.Add(new CodeTypeDeclaration()); + e.Types.Add(new CodeTypeDelegate("name")); + int generateTypeStartCallCount = 0; + int generateTypeEndCallCount = 0; + generator.GenerateTypeStartAction = (actualE) => + { + Assert.Same(e.Types[generateTypeStartCallCount], actualE); + Assert.Equal(generateTypeStartCallCount, generateTypeEndCallCount); + writer.Write("TypeStart "); + generateTypeStartCallCount++; + }; + generator.GenerateTypeEndAction = (actualE) => + { + Assert.Same(e.Types[generateTypeEndCallCount], actualE); + writer.Write("TypeEnd"); + generateTypeEndCallCount++; + }; + generator.GenerateTypes(e); + Assert.Equal($"{Environment.NewLine}TypeStart TypeEnd{Environment.NewLine}TypeStart TypeEnd", writer.ToString()); + Assert.Equal(2, generateTypeStartCallCount); + Assert.Equal(2, generateTypeEndCallCount); + + Assert.Same(e.Types[1], generator.CurrentClass); + Assert.Null(generator.CurrentMember); + Assert.Equal("<% unknown %>", generator.CurrentMemberName); + Assert.Same(e.Types[1].Name, generator.CurrentTypeName); + Assert.False(generator.IsCurrentClass); + Assert.True(generator.IsCurrentDelegate); + Assert.False(generator.IsCurrentEnum); + Assert.False(generator.IsCurrentInterface); + Assert.False(generator.IsCurrentStruct); + }); + } + + [Fact] + public void GenerateTypes_InvokeWithCommentsDirectivesAndLinePragma_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var type = new CodeTypeDeclaration { LinePragma = new CodeLinePragma() }; + type.Comments.Add(new CodeCommentStatement("Comment")); + type.Comments.Add(new CodeCommentStatement("Comment")); + type.StartDirectives.Add(new CodeDirective()); + type.StartDirectives.Add(new CodeChecksumPragma()); + type.StartDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + type.EndDirectives.Add(new CodeDirective()); + type.EndDirectives.Add(new CodeChecksumPragma()); + type.EndDirectives.Add(new CodeChecksumPragma("fileName", Guid.NewGuid(), new byte[0])); + var e = new CodeNamespace(); + e.Types.Add(type); + + int generateCommentStatementsCallCount = 0; + int generateCommentCallCount = 0; + int generateLinePragmaStartCallCount = 0; + int generateTypeStartCallCount = 0; + int generateTypeEndCallCount = 0; + int generateDirectivesCallCount = 0; + int generateLinePragmaEndCallCount = 0; + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(type.Comments, actualE); + writer.Write("Comments "); + Assert.Equal(0, generateLinePragmaStartCallCount); + Assert.Equal(0, generateTypeStartCallCount); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(0, generateTypeEndCallCount); + generateCommentStatementsCallCount++; + }; + generator.GenerateCommentAction = (actualE) => + { + Assert.Same(type.Comments[generateCommentCallCount].Comment, actualE); + writer.Write("Comment "); + generateCommentCallCount++; + }; + generator.GenerateLinePragmaStartAction = (actualE) => + { + Assert.Same(type.LinePragma, actualE); + Assert.Equal(0, generateTypeStartCallCount); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(0, generateTypeEndCallCount); + writer.Write("LinePragmaStart "); + generateLinePragmaStartCallCount++; + }; + generator.GenerateTypeStartAction = (actualE) => + { + Assert.Same(type, actualE); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(0, generateLinePragmaEndCallCount); + Assert.Equal(0, generateTypeEndCallCount); + writer.Write("TypeStart "); + generateTypeStartCallCount++; + }; + generator.GenerateTypeEndAction = (actualE) => + { + Assert.Same(type, actualE); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(0, generateLinePragmaEndCallCount); + writer.Write("TypeEnd "); + generateTypeEndCallCount++; + }; + generator.GenerateLinePragmaEndAction = (actualE) => + { + Assert.Same(type.LinePragma, actualE); + Assert.Equal(1, generateDirectivesCallCount); + Assert.Equal(1, generateTypeEndCallCount); + writer.Write("LinePragmaEnd "); + generateLinePragmaEndCallCount++; + }; + generator.GenerateDirectivesAction = (actualDirectives, baseMethod) => + { + baseMethod(actualDirectives); + Assert.Same(generateDirectivesCallCount == 0 ? type.StartDirectives : type.EndDirectives, actualDirectives); + writer.Write(generateDirectivesCallCount == 0 ? "StartDirectives " : "EndDirectives"); + generateDirectivesCallCount++; + }; + generator.GenerateTypes(e); + Assert.Equal($"{Environment.NewLine}StartDirectives Comment Comment Comments LinePragmaStart TypeStart TypeEnd LinePragmaEnd EndDirectives", writer.ToString()); + Assert.Equal(1, generateCommentStatementsCallCount); + Assert.Equal(2, generateCommentCallCount); + Assert.Equal(1, generateLinePragmaStartCallCount); + Assert.Equal(1, generateTypeStartCallCount); + Assert.Equal(1, generateTypeEndCallCount); + Assert.Equal(1, generateLinePragmaEndCallCount); + Assert.Equal(2, generateDirectivesCallCount); + + Assert.Same(type, generator.CurrentClass); + Assert.Null(generator.CurrentMember); + Assert.Equal("<% unknown %>", generator.CurrentMemberName); + Assert.Same(type.Name, generator.CurrentTypeName); + Assert.Equal(type.IsClass, generator.IsCurrentClass); + Assert.False(generator.IsCurrentDelegate); + Assert.Equal(type.IsEnum, generator.IsCurrentEnum); + Assert.Equal(type.IsInterface, generator.IsCurrentInterface); + Assert.Equal(type.IsStruct, generator.IsCurrentStruct); + }); + } + + [Fact] + public void GenerateTypes_InvokeWithMembers_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var type = new CodeTypeDeclaration(); + type.Members.Add(new CodeTypeMember()); + var e = new CodeNamespace(); + e.Types.Add(type); + + int generateTypeStartCallCount = 0; + int generateTypeEndCallCount = 0; + generator.GenerateTypeStartAction = (actualE) => + { + Assert.Same(type, actualE); + Assert.Equal(0, generateTypeEndCallCount); + writer.Write("TypeStart "); + generateTypeStartCallCount++; + }; + generator.GenerateTypeEndAction = (actualE) => + { + Assert.Same(type, actualE); + writer.Write("TypeEnd"); + generateTypeEndCallCount++; + }; + generator.GenerateTypes(e); + Assert.Equal($"{Environment.NewLine}TypeStart TypeEnd", writer.ToString()); + Assert.Equal(1, generateTypeStartCallCount); + Assert.Equal(1, generateTypeEndCallCount); + Assert.Same(type, generator.CurrentClass); + }); + } + + [Fact] + public void GenerateTypes_InvokeEmpty_Nop() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var e = new CodeNamespace(); + generator.GenerateTypes(e); + Assert.Empty(writer.ToString()); + }); + } + + [Fact] + public void GenerateTypes_InvokeEmptyEWithoutWriter_Nop() + { + CodeGeneratorTests generator = this; + var e = new CodeNamespace(); + generator.GenerateTypes(e); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void GenerateTypes_NullE_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + Assert.Throws("e", () => generator.GenerateTypes(null)); + } + + [Fact] + public void GenerateTypes_NullValueInE_ThrowsArgumentException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var type = new CodeTypeDeclaration(); + type.Comments.Add(new CodeCommentStatement()); + var e = new CodeNamespace(); + e.Types.Add(type); + + generator.GenerateNamespaceAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateCommentStatementsAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateNamespaceStartAction = (actualE) => {}; + generator.GenerateNamespaceEndAction = (actualE) => {}; + + Assert.Throws("e", () => generator.GenerateTypes(e)); + }); + } + + [Theory] + [InlineData(null, false)] + [InlineData("", false)] + [InlineData(" ", false)] + [InlineData("a", true)] + [InlineData("A", true)] + [InlineData("\u01C5", true)] + [InlineData("\u02B0", true)] + [InlineData("\u2163", true)] + [InlineData("\u0620", true)] + [InlineData("_", true)] + [InlineData("_aA\u01C5\u02B0\u2163\u0620_0", true)] + [InlineData("aA\u01C5\u02B0\u2163\u0620_0", true)] + [InlineData(" ", false)] + [InlineData("a ", false)] + [InlineData("#", false)] + [InlineData("a#", false)] + [InlineData("\u0300", false)] + [InlineData("a\u0300", true)] + [InlineData("\u0903", false)] + [InlineData("a\u0903", true)] + [InlineData("\u203F", false)] + [InlineData("a\u203F", true)] + [InlineData("0", false)] + [InlineData("1", false)] + [InlineData(":", false)] + [InlineData(".", false)] + [InlineData("$", false)] + [InlineData("+", false)] + [InlineData("<", false)] + [InlineData(">", false)] + [InlineData("-", false)] + [InlineData("[", false)] + [InlineData("]", false)] + [InlineData(",", false)] + [InlineData("&", false)] + [InlineData("*", false)] + [InlineData("`", false)] + [InlineData("a0", true)] + [InlineData("a1", true)] + [InlineData("a:", false)] + [InlineData("a.", false)] + [InlineData("a$", false)] + [InlineData("a+", false)] + [InlineData("a<", false)] + [InlineData("a>", false)] + [InlineData("a-", false)] + [InlineData("a[", false)] + [InlineData("a]", false)] + [InlineData("a,", false)] + [InlineData("a&", false)] + [InlineData("a*", false)] + [InlineData("\0", false)] + [InlineData("a\0", false)] + [InlineData("\r", false)] + [InlineData("a\r", false)] + [InlineData("\n", false)] + [InlineData("a\n", false)] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void IsValidLanguageIndependentIdentifier_Invoke_ReturnsExpected(string value, bool expected) + { + Assert.Equal(expected, CodeGenerator.IsValidLanguageIndependentIdentifier(value)); + } + + [Theory] + [InlineData(null, "1")] + [InlineData("", "1")] + [InlineData("name", "name=1")] + public void OutputAttributeArgument_Invoke_Success(string name, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var arg = new CodeAttributeArgument(name, new CodePrimitiveExpression(1)); + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.OutputAttributeArgument(arg); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void OutputAttributeArgument_NullArg_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("arg", () => generator.OutputAttributeArgument(null)); + } + + [Fact] + public void OutputAttributeArgument_NullArgValue_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var arg = new CodeAttributeArgument(); + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws("e", () => generator.OutputAttributeArgument(arg)); + }); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("name")] + public void OutputAttributeArgument_InvokeNonNullNameWithoutOutput_ThrowsNullReferenceException(string name) + { + CodeGeneratorTests generator = this; + var arg = new CodeAttributeArgument(name, new CodePrimitiveExpression(1)); + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + Assert.Throws(() => generator.OutputAttributeArgument(arg)); + } + + [Fact] + public void OutputAttributeDeclarations_NonEmptyAttributes_Success() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var attributes = new CodeAttributeDeclarationCollection(new CodeAttributeDeclaration[] + { + new CodeAttributeDeclaration(), + new CodeAttributeDeclaration(string.Empty), + new CodeAttributeDeclaration("name"), + new CodeAttributeDeclaration("name", new CodeAttributeArgument(new CodePrimitiveExpression(1))), + new CodeAttributeDeclaration("name", new CodeAttributeArgument("AttributeName", new CodePrimitiveExpression(1))), + new CodeAttributeDeclaration("name", new CodeAttributeArgument("AttributeName1", new CodePrimitiveExpression(1)), new CodeAttributeArgument("AttributeName2", new CodePrimitiveExpression(2))) + }); + int generateAttributeDeclarationsStartCallCount = 0; + int generateAttributeDeclarationsEndCallCount = 0; + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.GenerateAttributeDeclarationsStartAction = (actualAttributes) => + { + Assert.Same(attributes, actualAttributes); + Assert.Equal(0, generateAttributeDeclarationsEndCallCount); + generator.Output.Write("StartAttributes "); + generateAttributeDeclarationsStartCallCount++; + }; + generator.OutputIdentifierAction = (actualIdentifier, baseMethod) => baseMethod(actualIdentifier); + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GeneratePrimitiveExpressionAction = (actualE, baseMethod) => baseMethod(actualE); + generator.GenerateAttributeDeclarationsEndAction = (actualAttributes) => + { + Assert.Same(attributes, actualAttributes); + generator.Output.Write(" EndAttributes"); + generateAttributeDeclarationsEndCallCount++; + }; + generator.OutputAttributeDeclarations(attributes); + Assert.Equal(1, generateAttributeDeclarationsStartCallCount); + Assert.Equal(1, generateAttributeDeclarationsStartCallCount); + Assert.Equal($"StartAttributes (), {Environment.NewLine}(), {Environment.NewLine}name(), {Environment.NewLine}name(1), {Environment.NewLine}name(AttributeName=1), {Environment.NewLine}name(AttributeName1=1, AttributeName2=2) EndAttributes", writer.ToString()); + }); + } + + [Fact] + public void OutputAttributeDeclarations_InvokeEmptyAttributes_Nop() + { + CodeGeneratorTests generator = this; + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputAttributeDeclarations(new CodeAttributeDeclarationCollection()); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void OutputAttributeDeclarations_NullAttributes_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + Assert.Throws("attributes", () => generator.OutputAttributeDeclarations(null)); + } + + [Fact] + public void OutputAttributeDeclarations_InvokeNonEmptyAttributesNoOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var attributes = new CodeAttributeDeclarationCollection(new CodeAttributeDeclaration[] + { + new CodeAttributeDeclaration(), + new CodeAttributeDeclaration(string.Empty), + new CodeAttributeDeclaration("name") + }); + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.GenerateAttributeDeclarationsStartAction = (actualAttributes) => {}; + generator.GenerateAttributeDeclarationsEndAction = (actualAttributes) => {}; + Assert.Throws(() => generator.OutputAttributeDeclarations(attributes)); + } + + [Fact] + public void OutputAttributeDeclarations_NullArgumentExpressionInAttributes_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var attributes = new CodeAttributeDeclarationCollection(new CodeAttributeDeclaration[] + { + new CodeAttributeDeclaration("name", new CodeAttributeArgument()) + }); + generator.OutputAttributeDeclarationsAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.GenerateAttributeDeclarationsStartAction = (actualAttributes) => { }; + generator.OutputAttributeArgumentAction = (actualArg, baseMethod) => baseMethod(actualArg); + generator.GenerateAttributeDeclarationsEndAction = (actualAttributes) => { }; + Assert.Throws("e", () => generator.OutputAttributeDeclarations(attributes)); + }); + } + + [Theory] + [InlineData(FieldDirection.In, "")] + [InlineData(FieldDirection.Out, "out ")] + [InlineData(FieldDirection.Ref, "ref ")] + [InlineData(FieldDirection.In - 1, "")] + [InlineData(FieldDirection.Ref + 1, "")] + public void OutputDirection_Invoke_Success(FieldDirection direction, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.OutputDirection(direction); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(FieldDirection.Out)] + [InlineData(FieldDirection.Ref)] + public void OutputDirection_InvokeWithoutOutput_ThrowsNullReferenceException(FieldDirection direction) + { + CodeGeneratorTests generator = this; + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + Assert.Throws(() => generator.OutputDirection(direction)); + } + + [Theory] + [InlineData(FieldDirection.In)] + [InlineData(FieldDirection.In - 1)] + [InlineData(FieldDirection.Ref + 1)] + public void OutputDirection_InvokeWithoutOutputInvaliddirection_Ndirection(FieldDirection direction) + { + CodeGeneratorTests generator = this; + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.OutputDirection(direction); + } + + [Theory] + [InlineData(MemberAttributes.Abstract, "")] + [InlineData(MemberAttributes.Final, "")] + [InlineData(MemberAttributes.Static, "static ")] + [InlineData(MemberAttributes.Override, "")] + [InlineData(MemberAttributes.Const, "const ")] + [InlineData(MemberAttributes.ScopeMask, "")] + [InlineData(MemberAttributes.New, "new ")] + [InlineData(MemberAttributes.VTableMask, "")] + [InlineData(MemberAttributes.Overloaded, "")] + [InlineData(MemberAttributes.Assembly, "")] + [InlineData(MemberAttributes.FamilyAndAssembly, "")] + [InlineData(MemberAttributes.Family, "")] + [InlineData(MemberAttributes.FamilyOrAssembly, "")] + [InlineData(MemberAttributes.Private, "")] + [InlineData(MemberAttributes.Public, "")] + [InlineData(MemberAttributes.AccessMask, "")] + [InlineData(MemberAttributes.New | MemberAttributes.Private, "new ")] + [InlineData(MemberAttributes.Static | MemberAttributes.Private, "static ")] + [InlineData(MemberAttributes.Const | MemberAttributes.Private, "const ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const, "new const ")] + public void OutputFieldScopeModifier_Invoke_Success(MemberAttributes attributes, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputFieldScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputFieldScopeModifier(attributes); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(MemberAttributes.Static)] + [InlineData(MemberAttributes.Const)] + [InlineData(MemberAttributes.New)] + [InlineData(MemberAttributes.New | MemberAttributes.Private)] + [InlineData(MemberAttributes.Static | MemberAttributes.Private)] + [InlineData(MemberAttributes.Const | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Static)] + [InlineData(MemberAttributes.New | MemberAttributes.Const)] + public void OutputFieldScopeModifier_InvokeWithoutOutput_ThrowsNullReferenceException(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputFieldScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + Assert.Throws(() => generator.OutputFieldScopeModifier(attributes)); + } + + [Theory] + [InlineData(MemberAttributes.Abstract)] + [InlineData(MemberAttributes.Final)] + [InlineData(MemberAttributes.Override)] + [InlineData(MemberAttributes.ScopeMask)] + [InlineData(MemberAttributes.VTableMask)] + [InlineData(MemberAttributes.Overloaded)] + [InlineData(MemberAttributes.Assembly)] + [InlineData(MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.Family)] + [InlineData(MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.Private)] + [InlineData(MemberAttributes.Public)] + [InlineData(MemberAttributes.AccessMask)] + public void OutputFieldScopeModifier_InvokeWithoutOutputInvalid_Nop(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputFieldScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputFieldScopeModifier(attributes); + } + + [Theory] + [InlineData(null, "")] + [InlineData("", "")] + [InlineData("ident", "ident")] + public void OutputIdentifier_InvokeWithOutput_Appends(string st, string expected) + { + CodeGeneratorTests generator = this; + generator.PerformActionWithOutput(writer => + { + generator.OutputIdentifierAction = (actualSt, baseMethod) => baseMethod(actualSt); + generator.OutputIdentifier(st); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("ident")] + public void OutputIdentifier_InvokeWithoutOutput_ThrowsNullReferenceException(string ident) + { + CodeGeneratorTests generator = this; + generator.OutputIdentifierAction = (actualSt, baseMethod) => baseMethod(actualSt); + Assert.Throws(() => generator.OutputIdentifier(ident)); + } + + [Theory] + [InlineData(MemberAttributes.Abstract, "")] + [InlineData(MemberAttributes.Final, "")] + [InlineData(MemberAttributes.Static, "")] + [InlineData(MemberAttributes.Override, "")] + [InlineData(MemberAttributes.Const, "")] + [InlineData(MemberAttributes.ScopeMask, "")] + [InlineData(MemberAttributes.New, "")] + [InlineData(MemberAttributes.VTableMask, "")] + [InlineData(MemberAttributes.Overloaded, "")] + [InlineData(MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.AccessMask, "")] + [InlineData(MemberAttributes.New | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Assembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyAndAssembly, "internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Family, "protected ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyOrAssembly, "protected internal ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Private, "private ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Public, "public ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Public, "public ")] + public void OutputMemberAccessModifier_Invoke_Success(MemberAttributes attributes, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputMemberAccessModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputMemberAccessModifier(attributes); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(MemberAttributes.Assembly)] + [InlineData(MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.Family)] + [InlineData(MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.Private)] + [InlineData(MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Public)] + public void OutputMemberAccessModifier_InvokeWithoutOutput_ThrowsNullReferenceException(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputMemberAccessModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + Assert.Throws(() => generator.OutputMemberAccessModifier(attributes)); + } + + [Theory] + [InlineData(MemberAttributes.Abstract)] + [InlineData(MemberAttributes.Final)] + [InlineData(MemberAttributes.Static)] + [InlineData(MemberAttributes.Override)] + [InlineData(MemberAttributes.Const)] + [InlineData(MemberAttributes.ScopeMask)] + [InlineData(MemberAttributes.New)] + [InlineData(MemberAttributes.VTableMask)] + [InlineData(MemberAttributes.Overloaded)] + [InlineData(MemberAttributes.AccessMask)] + public void OutputMemberAccessModifier_InvokeWithoutOutputInvalid_Nop(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputMemberAccessModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputMemberAccessModifier(attributes); + } + + [Theory] + [InlineData(MemberAttributes.Abstract, "abstract ")] + [InlineData(MemberAttributes.Final, "")] + [InlineData(MemberAttributes.Static, "static ")] + [InlineData(MemberAttributes.Override, "override ")] + [InlineData(MemberAttributes.Const, "")] + [InlineData(MemberAttributes.ScopeMask, "")] + [InlineData(MemberAttributes.New, "new ")] + [InlineData(MemberAttributes.VTableMask, "")] + [InlineData(MemberAttributes.Overloaded, "")] + [InlineData(MemberAttributes.Assembly, "")] + [InlineData(MemberAttributes.FamilyAndAssembly, "")] + [InlineData(MemberAttributes.Family, "virtual ")] + [InlineData(MemberAttributes.FamilyOrAssembly, "")] + [InlineData(MemberAttributes.Private, "")] + [InlineData(MemberAttributes.Public, "virtual ")] + [InlineData(MemberAttributes.AccessMask, "")] + [InlineData(MemberAttributes.New | MemberAttributes.Assembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyAndAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Family, "new virtual ")] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyOrAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Private, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Public, "new virtual ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Assembly, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Assembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Assembly, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Assembly, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Assembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyAndAssembly, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyAndAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyAndAssembly, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyAndAssembly, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyAndAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Family, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Family, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Family, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Family, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Family, "new virtual ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyOrAssembly, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyOrAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyOrAssembly, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyOrAssembly, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyOrAssembly, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Private, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Private, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Private, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Private, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Private, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Public, "new abstract ")] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Public, "new ")] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Public, "new static ")] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Public, "new override ")] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Public, "new virtual ")] + public void OutputMemberScopeModifier_Invoke_Success(MemberAttributes attributes, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputMemberScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputMemberScopeModifier(attributes); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(MemberAttributes.Abstract)] + [InlineData(MemberAttributes.Final)] + [InlineData(MemberAttributes.Static)] + [InlineData(MemberAttributes.Override)] + [InlineData(MemberAttributes.New)] + [InlineData(MemberAttributes.Family)] + [InlineData(MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Assembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Family)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Private)] + [InlineData(MemberAttributes.New | MemberAttributes.Abstract | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Final | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Static | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Override | MemberAttributes.Public)] + [InlineData(MemberAttributes.New | MemberAttributes.Const | MemberAttributes.Public)] + public void OutputMemberScopeModifier_InvokeWithoutOutput_ThrowsNullReferenceException(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputMemberScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + Assert.Throws(() => generator.OutputMemberScopeModifier(attributes)); + } + + [Theory] + [InlineData(MemberAttributes.Const)] + [InlineData(MemberAttributes.ScopeMask)] + [InlineData(MemberAttributes.VTableMask)] + [InlineData(MemberAttributes.Overloaded)] + [InlineData(MemberAttributes.Assembly)] + [InlineData(MemberAttributes.FamilyAndAssembly)] + [InlineData(MemberAttributes.FamilyOrAssembly)] + [InlineData(MemberAttributes.Private)] + [InlineData(MemberAttributes.AccessMask)] + public void OutputMemberScopeModifier_InvokeWithoutOutputInvalid_Nop(MemberAttributes attributes) + { + CodeGeneratorTests generator = this; + generator.OutputMemberScopeModifierAction = (actualAttributes, baseMethod) => baseMethod(actualAttributes); + generator.OutputMemberScopeModifier(attributes); + } + + [Theory] + [InlineData(CodeBinaryOperatorType.Add, "+")] + [InlineData(CodeBinaryOperatorType.Assign, "=")] + [InlineData(CodeBinaryOperatorType.BitwiseAnd, "&")] + [InlineData(CodeBinaryOperatorType.BitwiseOr, "|")] + [InlineData(CodeBinaryOperatorType.BooleanAnd, "&&")] + [InlineData(CodeBinaryOperatorType.BooleanOr, "||")] + [InlineData(CodeBinaryOperatorType.Divide, "/")] + [InlineData(CodeBinaryOperatorType.GreaterThan, ">")] + [InlineData(CodeBinaryOperatorType.GreaterThanOrEqual, ">=")] + [InlineData(CodeBinaryOperatorType.IdentityEquality, "==")] + [InlineData(CodeBinaryOperatorType.IdentityInequality, "!=")] + [InlineData(CodeBinaryOperatorType.LessThan, "<")] + [InlineData(CodeBinaryOperatorType.LessThanOrEqual, "<=")] + [InlineData(CodeBinaryOperatorType.Modulus, "%")] + [InlineData(CodeBinaryOperatorType.Multiply, "*")] + [InlineData(CodeBinaryOperatorType.Subtract, "-")] + [InlineData(CodeBinaryOperatorType.ValueEquality, "==")] + [InlineData(CodeBinaryOperatorType.Add - 1, "")] + [InlineData(CodeBinaryOperatorType.GreaterThanOrEqual + 1, "")] + public void OutputOperator_Invoke_Success(CodeBinaryOperatorType op, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.OutputOperator(op); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(CodeBinaryOperatorType.Add)] + [InlineData(CodeBinaryOperatorType.Assign)] + [InlineData(CodeBinaryOperatorType.BitwiseAnd)] + [InlineData(CodeBinaryOperatorType.BitwiseOr)] + [InlineData(CodeBinaryOperatorType.BooleanAnd)] + [InlineData(CodeBinaryOperatorType.BooleanOr)] + [InlineData(CodeBinaryOperatorType.Divide)] + [InlineData(CodeBinaryOperatorType.GreaterThan)] + [InlineData(CodeBinaryOperatorType.GreaterThanOrEqual)] + [InlineData(CodeBinaryOperatorType.IdentityEquality)] + [InlineData(CodeBinaryOperatorType.IdentityInequality)] + [InlineData(CodeBinaryOperatorType.LessThan)] + [InlineData(CodeBinaryOperatorType.LessThanOrEqual)] + [InlineData(CodeBinaryOperatorType.Modulus)] + [InlineData(CodeBinaryOperatorType.Multiply)] + [InlineData(CodeBinaryOperatorType.Subtract)] + [InlineData(CodeBinaryOperatorType.ValueEquality)] + public void OutputOperator_InvokeWithoutOutput_ThrowsNullReferenceException(CodeBinaryOperatorType op) + { + CodeGeneratorTests generator = this; + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + Assert.Throws(() => generator.OutputOperator(op)); + } + + [Theory] + [InlineData(CodeBinaryOperatorType.Add - 1)] + [InlineData(CodeBinaryOperatorType.GreaterThanOrEqual + 1)] + public void OutputOperator_InvokeWithoutOutputInvalidOp_Nop(CodeBinaryOperatorType op) + { + CodeGeneratorTests generator = this; + generator.OutputOperatorAction = (actualOp, baseMethod) => baseMethod(actualOp); + generator.OutputOperator(op); + } + + public static IEnumerable OutputParameter_TestData() + { + yield return new object[] { new CodeParameterDeclarationExpression[0], "" }; + yield return new object[] { new CodeParameterDeclarationExpression[] { new CodeParameterDeclarationExpression() }, "Type " }; + yield return new object[] { new CodeParameterDeclarationExpression[] { new CodeParameterDeclarationExpression("type1", "name1"), new CodeParameterDeclarationExpression("type2", "name2") }, "Type name1, Type name2" }; + yield return new object[] + { + new CodeParameterDeclarationExpression[] + { + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression() + }, + "Type , Type , Type , Type , Type , Type , Type , Type , Type , Type , Type , Type , Type , Type , Type " + }; + yield return new object[] + { + new CodeParameterDeclarationExpression[] + { + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), + new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression(), new CodeParameterDeclarationExpression() + }, + $"{Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type , {Environment.NewLine}Type " + }; + } + + [Theory] + [MemberData(nameof(OutputParameter_TestData))] + public void OutputParameter_Invoke_Success(CodeParameterDeclarationExpression[] parametersArray, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + var parameters = new CodeParameterDeclarationExpressionCollection(parametersArray); + generator.OutputParametersAction = (actualParameters, baseMethod) => baseMethod(actualParameters); + int generateParameterDeclarationExpressionCallCount = 0; + int outputTypeActionCallCount = 0; + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(parameters[generateParameterDeclarationExpressionCallCount], actualE); + generateParameterDeclarationExpressionCallCount++; + }; + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.OutputTypeNamePairAction = (actualTypeRef, actualName, baseMethod) => baseMethod(actualTypeRef, actualName); + generator.OutputTypeAction = (actualTypeRef) => + { + Assert.Same(parameters[generateParameterDeclarationExpressionCallCount].Type, actualTypeRef); + writer.Write("Type"); + outputTypeActionCallCount++; + }; + generator.OutputIdentifierAction = (actualTypeRef, baseMethod) => baseMethod(actualTypeRef); + generator.OutputParameters(parameters); + Assert.Equal(expected, writer.ToString()); + Assert.Equal(parameters.Count, generateParameterDeclarationExpressionCallCount); + Assert.Equal(parameters.Count, outputTypeActionCallCount); + + // Call again to make sure indent is reset. + Assert.Equal(expected, writer.ToString()); + Assert.Equal(parameters.Count, generateParameterDeclarationExpressionCallCount); + Assert.Equal(parameters.Count, outputTypeActionCallCount); + }); + } + + [Fact] + public void OutputParameters_EmptyParametersWithoutWriter_Nop() + { + CodeGeneratorTests generator = this; + var parameters = new CodeParameterDeclarationExpressionCollection(); + generator.OutputParametersAction = (actualParameters, baseMethod) => baseMethod(actualParameters); + generator.OutputParameters(parameters); + } + + [Fact] + public void OutputParameters_InvokeWithoutWriter_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var parameters = new CodeParameterDeclarationExpressionCollection(new CodeParameterDeclarationExpression[] { new CodeParameterDeclarationExpression() }); + generator.OutputParametersAction = (actualParameters, baseMethod) => baseMethod(actualParameters); + int generateParameterDeclarationExpressionCallCount = 0; + generator.GenerateParameterDeclarationExpressionAction = (actualE, baseMethod) => + { + baseMethod(actualE); + Assert.Same(parameters[generateParameterDeclarationExpressionCallCount], actualE); + generateParameterDeclarationExpressionCallCount++; + }; + generator.OutputDirectionAction = (actualDirection, baseMethod) => baseMethod(actualDirection); + generator.OutputTypeNamePairAction = (actualTypeRef, actualName, baseMethod) => baseMethod(actualTypeRef, actualName); + generator.OutputTypeAction = (actualTypeRef) => { }; + Assert.Throws(() => generator.OutputParameters(parameters)); + } + + [Fact] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void OutputParameters_NullParameters_ThrowsArgumentNullException() + { + CodeGeneratorTests generator = this; + generator.OutputParametersAction = (actualParameters, baseMethod) => baseMethod(actualParameters); + Assert.Throws("parameters", () => generator.OutputParameters(null)); + } + + public static IEnumerable OutputTypeNamePair_TestData() + { + yield return new object[] { null, null }; + yield return new object[] { new CodeTypeReference(), "" }; + yield return new object[] { new CodeTypeReference(), "name" }; + } + + [Theory] + [MemberData(nameof(OutputTypeNamePair_TestData))] + public void OutputTypeNamePair_Invoke_Success(CodeTypeReference typeRef, string name) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputTypeNamePairAction = (actualTypeRef, actualName, baseMethod) => baseMethod(actualTypeRef, actualName); + int outputTypeCallCount = 0; + int outputIdentifierCallCount = 0; + generator.OutputTypeAction = (actualTypeRef) => + { + Assert.Same(typeRef, actualTypeRef); + Assert.Equal(0, outputIdentifierCallCount); + writer.Write("Type"); + outputTypeCallCount++; + }; + generator.OutputIdentifierAction = (actualIdent, baseMethod) => + { + baseMethod(actualIdent); + outputIdentifierCallCount++; + }; + generator.OutputTypeNamePair(typeRef, name); + Assert.Equal($"Type {name}", writer.ToString()); + Assert.Equal(1, outputTypeCallCount); + Assert.Equal(1, outputIdentifierCallCount); + }); + } + + [Fact] + public void OutputTypeNamePair_InvokeWithoutOutput_ThrowsNullReferenceException() + { + CodeGeneratorTests generator = this; + var typeRef = new CodeTypeReference(); + generator.OutputTypeNamePairAction = (actualTypeRef, actualName, baseMethod) => baseMethod(actualTypeRef, actualName); + generator.OutputTypeAction = (actualTypeRef) => {}; + Assert.Throws(() => generator.OutputTypeNamePair(typeRef, "name")); + } + + [Theory] + [InlineData(TypeAttributes.NotPublic, false, false, "class ")] + [InlineData(TypeAttributes.NotPublic, true, false, "struct ")] + [InlineData(TypeAttributes.NotPublic, true, true, "struct ")] + [InlineData(TypeAttributes.NotPublic, false, true, "enum ")] + [InlineData(TypeAttributes.Public, false, false, "public class ")] + [InlineData(TypeAttributes.Public, true, false, "public struct ")] + [InlineData(TypeAttributes.Public, true, true, "public struct ")] + [InlineData(TypeAttributes.Public, false, true, "public enum ")] + [InlineData(TypeAttributes.NestedPublic, false, false, "public class ")] + [InlineData(TypeAttributes.NestedPublic, true, false, "public struct ")] + [InlineData(TypeAttributes.NestedPublic, true, true, "public struct ")] + [InlineData(TypeAttributes.NestedPublic, false, true, "public enum ")] + [InlineData(TypeAttributes.NestedPrivate, false, false, "private class ")] + [InlineData(TypeAttributes.NestedPrivate, true, false, "private struct ")] + [InlineData(TypeAttributes.NestedPrivate, true, true, "private struct ")] + [InlineData(TypeAttributes.NestedPrivate, false, true, "private enum ")] + [InlineData(TypeAttributes.NestedFamily, false, false, "class ")] + [InlineData(TypeAttributes.NestedAssembly, false, false, "class ")] + [InlineData(TypeAttributes.NestedFamANDAssem, false, false, "class ")] + [InlineData(TypeAttributes.NestedFamORAssem, false, false, "class ")] + [InlineData(TypeAttributes.SequentialLayout, false, false, "class ")] + [InlineData(TypeAttributes.ExplicitLayout, false, false, "class ")] + [InlineData(TypeAttributes.LayoutMask, false, false, "class ")] + [InlineData(TypeAttributes.Interface, false, false, "interface ")] + [InlineData(TypeAttributes.Abstract, false, false, "abstract class ")] + [InlineData(TypeAttributes.Abstract, true, false, "struct ")] + [InlineData(TypeAttributes.Abstract, true, true, "struct ")] + [InlineData(TypeAttributes.Abstract, false, true, "enum ")] + [InlineData(TypeAttributes.Sealed, false, false, "sealed class ")] + [InlineData(TypeAttributes.Sealed, true, false, "struct ")] + [InlineData(TypeAttributes.Sealed, true, true, "struct ")] + [InlineData(TypeAttributes.Sealed, false, true, "enum ")] + [InlineData(TypeAttributes.SpecialName, false, false, "class ")] + [InlineData(TypeAttributes.RTSpecialName, false, false, "class ")] + [InlineData(TypeAttributes.Import, false, false, "class ")] + [InlineData(TypeAttributes.Serializable, false, false, "class ")] + [InlineData(TypeAttributes.WindowsRuntime, false, false, "class ")] + [InlineData(TypeAttributes.UnicodeClass, false, false, "class ")] + [InlineData(TypeAttributes.AutoClass, false, false, "class ")] + [InlineData(TypeAttributes.CustomFormatClass, false, false, "class ")] + [InlineData(TypeAttributes.HasSecurity, false, false, "class ")] + [InlineData(TypeAttributes.ReservedMask, false, false, "class ")] + [InlineData(TypeAttributes.BeforeFieldInit, false, false, "class ")] + [InlineData(TypeAttributes.CustomFormatMask, false, false, "class ")] + public void OutputTypeAttributes_Invoke_Success(TypeAttributes attributes, bool isStruct, bool isEnum, string expected) + { + CodeGeneratorTests generator = this; + PerformActionWithOutput(writer => + { + generator.OutputTypeAttributesAction = (actualAttributes, isStruct, isEnum, baseMethod) => baseMethod(actualAttributes, isStruct, isEnum); + generator.OutputTypeAttributes(attributes, isStruct, isEnum); + Assert.Equal(expected, writer.ToString()); + }); + } + + [Theory] + [InlineData(TypeAttributes.NotPublic, false, false)] + [InlineData(TypeAttributes.NotPublic, true, false)] + [InlineData(TypeAttributes.NotPublic, true, true)] + [InlineData(TypeAttributes.NotPublic, false, true)] + [InlineData(TypeAttributes.Public, false, false)] + [InlineData(TypeAttributes.Public, true, false)] + [InlineData(TypeAttributes.Public, true, true)] + [InlineData(TypeAttributes.Public, false, true)] + [InlineData(TypeAttributes.NestedPublic, false, false)] + [InlineData(TypeAttributes.NestedPublic, true, false)] + [InlineData(TypeAttributes.NestedPublic, true, true)] + [InlineData(TypeAttributes.NestedPublic, false, true)] + [InlineData(TypeAttributes.NestedPrivate, false, false)] + [InlineData(TypeAttributes.NestedPrivate, true, false)] + [InlineData(TypeAttributes.NestedPrivate, true, true)] + [InlineData(TypeAttributes.NestedPrivate, false, true)] + [InlineData(TypeAttributes.NestedFamily, false, false)] + [InlineData(TypeAttributes.NestedAssembly, false, false)] + [InlineData(TypeAttributes.NestedFamANDAssem, false, false)] + [InlineData(TypeAttributes.NestedFamORAssem, false, false)] + [InlineData(TypeAttributes.SequentialLayout, false, false)] + [InlineData(TypeAttributes.ExplicitLayout, false, false)] + [InlineData(TypeAttributes.LayoutMask, false, false)] + [InlineData(TypeAttributes.Interface, false, false)] + [InlineData(TypeAttributes.Abstract, false, false)] + [InlineData(TypeAttributes.Abstract, true, false)] + [InlineData(TypeAttributes.Abstract, true, true)] + [InlineData(TypeAttributes.Abstract, false, true)] + [InlineData(TypeAttributes.Sealed, false, false)] + [InlineData(TypeAttributes.Sealed, true, false)] + [InlineData(TypeAttributes.Sealed, true, true)] + [InlineData(TypeAttributes.Sealed, false, true)] + [InlineData(TypeAttributes.SpecialName, false, false)] + [InlineData(TypeAttributes.RTSpecialName, false, false)] + [InlineData(TypeAttributes.Import, false, false)] + [InlineData(TypeAttributes.Serializable, false, false)] + [InlineData(TypeAttributes.WindowsRuntime, false, false)] + [InlineData(TypeAttributes.UnicodeClass, false, false)] + [InlineData(TypeAttributes.AutoClass, false, false)] + [InlineData(TypeAttributes.CustomFormatClass, false, false)] + [InlineData(TypeAttributes.HasSecurity, false, false)] + [InlineData(TypeAttributes.ReservedMask, false, false)] + [InlineData(TypeAttributes.BeforeFieldInit, false, false)] + [InlineData(TypeAttributes.CustomFormatMask, false, false)] + public void OutputTypeAttributes_InvokeWithoutWriter_ThrowsNullReferenceException(TypeAttributes attributes, bool isStruct, bool isEnum) + { + CodeGeneratorTests generator = this; + generator.OutputTypeAttributesAction = (actualAttributes, isStruct, isEnum, baseMethod) => baseMethod(actualAttributes, isStruct, isEnum); + Assert.Throws(() => generator.OutputTypeAttributes(attributes, isStruct, isEnum)); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("value")] + public void ValidateIdentifier_InvokeValid_Nop(string value) + { + CodeGeneratorTests generator = this; + int isValidIdentifierCallCount = 0; + generator.ValidateIdentifierAction = (actualValue, baseMethod) => baseMethod(actualValue); + generator.IsValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + isValidIdentifierCallCount++; + return true; + }; + generator.ValidateIdentifier(value); + Assert.Equal(1, isValidIdentifierCallCount); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("value")] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void ValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string value) + { + CodeGeneratorTests generator = this; + int isValidIdentifierCallCount = 0; + generator.ValidateIdentifierAction = (actualValue, baseMethod) => baseMethod(actualValue); + generator.IsValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + isValidIdentifierCallCount++; + return false; + }; + Assert.Throws("value", () => generator.ValidateIdentifier(value)); + Assert.Equal(1, isValidIdentifierCallCount); + } + + [Theory] + [InlineData(null, null)] + [InlineData(null, "")] + [InlineData(null, "identifier")] + [InlineData("", null)] + [InlineData("", "")] + [InlineData("", "identifier")] + [InlineData("identifier", null)] + [InlineData("identifier", "")] + [InlineData("identifier", "escapedIdentifier")] + public void ICodeGeneratorCreateEscapedIdentifier_Invoke_ReturnsExpected(string value, string result) + { + CodeGeneratorTests generator = this; + int callCount = 0; + generator.CreateEscapedIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + callCount++; + return result; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Equal(result, iCodeGenerator.CreateEscapedIdentifier(value)); + Assert.Equal(1, callCount); + } + + [Theory] + [InlineData(null, null)] + [InlineData(null, "")] + [InlineData(null, "identifier")] + [InlineData("", null)] + [InlineData("", "")] + [InlineData("", "identifier")] + [InlineData("identifier", null)] + [InlineData("identifier", "")] + [InlineData("identifier", "validIdentifier")] + public void ICodeGeneratorCreateValidIdentifier_Invoke_ReturnsExpected(string value, string result) + { + CodeGeneratorTests generator = this; + int callCount = 0; + generator.CreateValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + callCount++; + return result; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Equal(result, iCodeGenerator.CreateValidIdentifier(value)); + Assert.Equal(1, callCount); + } + + public static IEnumerable GetTypeOutput_TestData() + { + yield return new object[] { null, null }; + yield return new object[] { null, string.Empty }; + yield return new object[] { null, "Output" }; + yield return new object[] { new CodeTypeReference(), null }; + yield return new object[] { new CodeTypeReference(), string.Empty }; + yield return new object[] { new CodeTypeReference(), "Output" }; + } + + [Theory] + [MemberData(nameof(GetTypeOutput_TestData))] + public void ICodeGeneratorGetTypeOutput_Invoke_ReturnsExpected(CodeTypeReference value, string result) + { + CodeGeneratorTests generator = this; + int callCount = 0; + generator.GetTypeOutputAction = (actualValue) => + { + Assert.Same(value, actualValue); + callCount++; + return result; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Equal(result, iCodeGenerator.GetTypeOutput(value)); + Assert.Equal(1, callCount); + } + + public static IEnumerable IsValidIdentifier_TestData() + { + foreach (bool result in new bool[] { true, false }) + { + yield return new object[] { null, result }; + yield return new object[] { "", result }; + yield return new object[] { "value", result }; + } + } + + [Theory] + [MemberData(nameof(IsValidIdentifier_TestData))] + public void ICodeGeneratorIsValidIdentifier_Invoke_ReturnsExpected(string value, bool result) + { + CodeGeneratorTests generator = this; + int callCount = 0; + generator.IsValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + callCount++; + return result; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Equal(result, iCodeGenerator.IsValidIdentifier(value)); + Assert.Equal(1, callCount); + } + + public static IEnumerable Supports_TestData() + { + foreach (bool result in new bool[] { true, false }) + { + yield return new object[] { GeneratorSupport.ArraysOfArrays - 1, result }; + yield return new object[] { GeneratorSupport.AssemblyAttributes, result }; + } + } + + [Theory] + [MemberData(nameof(Supports_TestData))] + public void ICodeGeneratorSupports_Invoke_ReturnsExpected(GeneratorSupport support, bool result) + { + CodeGeneratorTests generator = this; + int callCount = 0; + generator.SupportsAction = (actualSupport) => + { + Assert.Equal(support, actualSupport); + callCount++; + return result; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Equal(result, iCodeGenerator.Supports(support)); + Assert.Equal(1, callCount); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("value")] + public void ICodeGeneratorValidateIdentifier_InvokeValid_Nop(string value) + { + CodeGeneratorTests generator = this; + int isValidIdentifierCallCount = 0; + generator.ValidateIdentifierAction = (actualValue, baseMethod) => baseMethod(actualValue); + generator.IsValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + isValidIdentifierCallCount++; + return true; + }; + ICodeGenerator iCodeGenerator = generator; + iCodeGenerator.ValidateIdentifier(value); + Assert.Equal(1, isValidIdentifierCallCount); + } + + [Theory] + [InlineData(null)] + [InlineData("")] + [InlineData("value")] + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Not fixed on NetFX")] + public void ICodeGeneratorValidateIdentifier_InvokeInvalid_ThrowsArgumentException(string value) + { + CodeGeneratorTests generator = this; + int isValidIdentifierCallCount = 0; + generator.ValidateIdentifierAction = (actualValue, baseMethod) => baseMethod(actualValue); + generator.IsValidIdentifierAction = (actualValue) => + { + Assert.Same(value, actualValue); + isValidIdentifierCallCount++; + return false; + }; + ICodeGenerator iCodeGenerator = generator; + Assert.Throws("value", () => iCodeGenerator.ValidateIdentifier(value)); + Assert.Equal(1, isValidIdentifierCallCount); + } + + private void PerformActionWithOutput(Action action, CodeGeneratorOptions options = null) + { + CodeGeneratorTests generator = this; + ICodeGenerator iCodeGenerator = generator; + var e = new CodeArrayCreateExpression(typeof(int)); + var writer = new StringWriter(); + int callCount = 0; + generator.GenerateArrayCreateExpressionAction = (actualE) => + { + Assert.Same(e, actualE); + Assert.Equal(0, generator.Indent); + Assert.NotNull(generator.Output); + if (options != null) + { + Assert.Same(options, generator.Options); + } + else + { + Assert.NotNull(generator.Options); + } + action(writer); + callCount++; + }; + + iCodeGenerator.GenerateCodeFromExpression(e, writer, options); + Assert.Equal(1, callCount); + } + + protected override string NullToken => "NullToken"; + + public Func CreateEscapedIdentifierAction { get; set; } + + protected override string CreateEscapedIdentifier(string value) + { + return CreateEscapedIdentifierAction(value); + } + + public Func CreateValidIdentifierAction { get; set; } + + protected override string CreateValidIdentifier(string value) + { + return CreateValidIdentifierAction(value); + } + + public Action GenerateArgumentReferenceExpressionAction { get; set; } + + protected override void GenerateArgumentReferenceExpression(CodeArgumentReferenceExpression e) + { + GenerateArgumentReferenceExpressionAction(e); + } + + public Action GenerateArrayCreateExpressionAction { get; set; } + + protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression e) + { + GenerateArrayCreateExpressionAction(e); + } + + public Action GenerateArrayIndexerExpressionAction { get; set; } + + protected override void GenerateArrayIndexerExpression(CodeArrayIndexerExpression e) + { + GenerateArrayIndexerExpressionAction(e); + } + + public Action GenerateAssignStatementAction { get; set; } + + protected override void GenerateAssignStatement(CodeAssignStatement e) + { + GenerateAssignStatementAction(e); + } + + public Action GenerateAttachEventStatementAction { get; set; } + + protected override void GenerateAttachEventStatement(CodeAttachEventStatement e) + { + GenerateAttachEventStatementAction(e); + } + + public Action GenerateAttributeDeclarationsEndAction { get; set; } + + protected override void GenerateAttributeDeclarationsEnd(CodeAttributeDeclarationCollection attributes) + { + GenerateAttributeDeclarationsEndAction(attributes); + } + + public Action GenerateAttributeDeclarationsStartAction { get; set; } + + protected override void GenerateAttributeDeclarationsStart(CodeAttributeDeclarationCollection attributes) + { + GenerateAttributeDeclarationsStartAction(attributes); + } + + public Action GenerateBaseReferenceExpressionAction { get; set; } + + protected override void GenerateBaseReferenceExpression(CodeBaseReferenceExpression e) + { + GenerateBaseReferenceExpressionAction(e); + } + + public Action GenerateCastExpressionAction { get; set; } + + protected override void GenerateCastExpression(CodeCastExpression e) + { + GenerateCastExpressionAction(e); + } + + public Action GenerateCommentAction { get; set; } + + protected override void GenerateComment(CodeComment e) + { + GenerateCommentAction(e); + } + + public Action> GenerateCommentStatementsAction { get; set; } + + protected override void GenerateCommentStatements(CodeCommentStatementCollection e) + { + if (e != null) + { + if (e.GetEnumerator().MoveNext()) + { + GenerateCommentStatementsAction(e, base.GenerateCommentStatements); + } + } + else + { + GenerateCommentStatementsAction(e, base.GenerateCommentStatements); + } + } + + public Action> GenerateCompileUnitAction { get; set; } + + protected override void GenerateCompileUnit(CodeCompileUnit e) + { + GenerateCompileUnitAction(e, base.GenerateCompileUnit); + } + + public Action> GenerateCompileUnitEndAction { get; set; } + + protected override void GenerateCompileUnitEnd(CodeCompileUnit e) + { + GenerateCompileUnitEndAction(e, base.GenerateCompileUnitEnd); + } + + public Action> GenerateCompileUnitStartAction { get; set; } + + protected override void GenerateCompileUnitStart(CodeCompileUnit e) + { + GenerateCompileUnitStartAction(e, base.GenerateCompileUnitStart); + } + + public Action GenerateConditionStatementAction { get; set; } + + protected override void GenerateConditionStatement(CodeConditionStatement e) + { + GenerateConditionStatementAction(e); + } + + public Action GenerateConstructorAction { get; set; } + + protected override void GenerateConstructor(CodeConstructor e, CodeTypeDeclaration c) + { + GenerateConstructorAction(e, c); + } + + public Action> GenerateDecimalValueAction { get; set; } + + protected override void GenerateDecimalValue(decimal d) + { + GenerateDecimalValueAction(d, base.GenerateDecimalValue); + } + + public Action> GenerateDefaultValueExpressionAction { get; set; } + + protected override void GenerateDefaultValueExpression(CodeDefaultValueExpression e) + { + GenerateDefaultValueExpressionAction(e, base.GenerateDefaultValueExpression); + } + + public Action GenerateDelegateCreateExpressionAction { get; set; } + + protected override void GenerateDelegateCreateExpression(CodeDelegateCreateExpression e) + { + GenerateDelegateCreateExpressionAction(e); + } + + public Action GenerateDelegateInvokeExpressionAction { get; set; } + + protected override void GenerateDelegateInvokeExpression(CodeDelegateInvokeExpression e) + { + GenerateDelegateInvokeExpressionAction(e); + } + + public Action> GenerateDirectionExpressionAction { get; set; } + + protected override void GenerateDirectionExpression(CodeDirectionExpression e) + { + GenerateDirectionExpressionAction(e, base.GenerateDirectionExpression); + } + + public Action> GenerateDirectivesAction { get; set; } + + protected override void GenerateDirectives(CodeDirectiveCollection directives) + { + if (directives != null && directives.GetEnumerator().MoveNext()) + { + GenerateDirectivesAction(directives, base.GenerateDirectives); } } + + public Action> GenerateDoubleValueAction { get; set; } + + protected override void GenerateDoubleValue(double d) + { + GenerateDoubleValueAction(d, base.GenerateDoubleValue); + } + + public Action GenerateEntryPointMethodAction { get; set; } + + protected override void GenerateEntryPointMethod(CodeEntryPointMethod e, CodeTypeDeclaration c) + { + GenerateEntryPointMethodAction(e, c); + } + + public Action GenerateEventAction { get; set; } + + protected override void GenerateEvent(CodeMemberEvent e, CodeTypeDeclaration c) + { + GenerateEventAction(e, c); + } + + public Action GenerateEventReferenceExpressionAction { get; set; } + + protected override void GenerateEventReferenceExpression(CodeEventReferenceExpression e) + { + GenerateEventReferenceExpressionAction(e); + } + + public Action GenerateExpressionStatementAction { get; set; } + + protected override void GenerateExpressionStatement(CodeExpressionStatement e) + { + GenerateExpressionStatementAction(e); + } + + public Action GenerateFieldAction { get; set; } + + protected override void GenerateField(CodeMemberField e) + { + GenerateFieldAction(e); + } + + public Action GenerateFieldReferenceExpressionAction { get; set; } + + protected override void GenerateFieldReferenceExpression(CodeFieldReferenceExpression e) + { + GenerateFieldReferenceExpressionAction(e); + } + + public Action GenerateGotoStatementAction { get; set; } + + protected override void GenerateGotoStatement(CodeGotoStatement e) + { + GenerateGotoStatementAction(e); + } + + public Action GenerateIndexerExpressionAction { get; set; } + + protected override void GenerateIndexerExpression(CodeIndexerExpression e) + { + GenerateIndexerExpressionAction(e); + } + + public Action GenerateIterationStatementAction { get; set; } + + protected override void GenerateIterationStatement(CodeIterationStatement e) + { + GenerateIterationStatementAction(e); + } + + public Action GenerateLabeledStatementAction { get; set; } + + protected override void GenerateLabeledStatement(CodeLabeledStatement e) + { + GenerateLabeledStatementAction(e); + } + + public Action GenerateLinePragmaEndAction { get; set; } + + protected override void GenerateLinePragmaEnd(CodeLinePragma e) + { + GenerateLinePragmaEndAction(e); + } + + public Action GenerateLinePragmaStartAction { get; set; } + + protected override void GenerateLinePragmaStart(CodeLinePragma e) + { + GenerateLinePragmaStartAction(e); + } + + public Action GenerateMethodAction { get; set; } + + protected override void GenerateMethod(CodeMemberMethod e, CodeTypeDeclaration c) + { + GenerateMethodAction(e, c); + } + + public Action GenerateMethodInvokeExpressionAction { get; set; } + + protected override void GenerateMethodInvokeExpression(CodeMethodInvokeExpression e) + { + GenerateMethodInvokeExpressionAction(e); + } + + public Action GenerateMethodReferenceExpressionAction { get; set; } + + protected override void GenerateMethodReferenceExpression(CodeMethodReferenceExpression e) + { + GenerateMethodReferenceExpressionAction(e); + } + + public Action GenerateMethodReturnStatementAction { get; set; } + + protected override void GenerateMethodReturnStatement(CodeMethodReturnStatement e) + { + GenerateMethodReturnStatementAction(e); + } + + public Action> GenerateNamespaceAction { get; set; } + + protected override void GenerateNamespace(CodeNamespace e) + { + GenerateNamespaceAction(e, base.GenerateNamespace); + } + + public Action GenerateNamespaceEndAction { get; set; } + + protected override void GenerateNamespaceEnd(CodeNamespace e) + { + GenerateNamespaceEndAction(e); + } + + public Action GenerateNamespaceImportAction { get; set; } + + protected override void GenerateNamespaceImport(CodeNamespaceImport e) + { + GenerateNamespaceImportAction(e); + } + + public Action GenerateNamespaceStartAction { get; set; } + + protected override void GenerateNamespaceStart(CodeNamespace e) + { + GenerateNamespaceStartAction(e); + } + + public Action GenerateObjectCreateExpressionAction { get; set; } + + protected override void GenerateObjectCreateExpression(CodeObjectCreateExpression e) + { + GenerateObjectCreateExpressionAction(e); + } + + public Action> GenerateParameterDeclarationExpressionAction { get; set; } + + protected override void GenerateParameterDeclarationExpression(CodeParameterDeclarationExpression e) + { + GenerateParameterDeclarationExpressionAction(e, base.GenerateParameterDeclarationExpression); + } + + public Action> GeneratePrimitiveExpressionAction { get; set; } + + protected override void GeneratePrimitiveExpression(CodePrimitiveExpression e) + { + GeneratePrimitiveExpressionAction(e, base.GeneratePrimitiveExpression); + } + + public Action GeneratePropertyAction { get; set; } + + protected override void GenerateProperty(CodeMemberProperty e, CodeTypeDeclaration c) + { + GeneratePropertyAction(e, c); + } + + public Action GeneratePropertyReferenceExpressionAction { get; set; } + + protected override void GeneratePropertyReferenceExpression(CodePropertyReferenceExpression e) + { + GeneratePropertyReferenceExpressionAction(e); + } + + public Action GeneratePropertySetValueReferenceExpressionAction { get; set; } + + protected override void GeneratePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e) + { + GeneratePropertySetValueReferenceExpressionAction(e); + } + + public Action GenerateRemoveEventStatementAction { get; set; } + + protected override void GenerateRemoveEventStatement(CodeRemoveEventStatement e) + { + GenerateRemoveEventStatementAction(e); + } + + public Action> GenerateSingleFloatValueAction { get; set; } + + protected override void GenerateSingleFloatValue(float s) + { + GenerateSingleFloatValueAction(s, base.GenerateSingleFloatValue); + } + + public Action GenerateSnippetExpressionAction { get; set; } + + protected override void GenerateSnippetExpression(CodeSnippetExpression e) + { + GenerateSnippetExpressionAction(e); + } + + public Action GenerateSnippetMemberAction { get; set; } + + protected override void GenerateSnippetMember(CodeSnippetTypeMember e) + { + GenerateSnippetMemberAction(e); + } + + public Action> GenerateSnippetStatementAction { get; set; } + + protected override void GenerateSnippetStatement(CodeSnippetStatement e) + { + GenerateSnippetStatementAction(e, base.GenerateSnippetStatement); + } + + public Action GenerateThisReferenceExpressionAction { get; set; } + + protected override void GenerateThisReferenceExpression(CodeThisReferenceExpression e) + { + GenerateThisReferenceExpressionAction(e); + } + + public Action GenerateThrowExceptionStatementAction { get; set; } + + protected override void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e) + { + GenerateThrowExceptionStatementAction(e); + } + + public Action GenerateTryCatchFinallyStatementAction { get; set; } + + protected override void GenerateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e) + { + GenerateTryCatchFinallyStatementAction(e); + } + + public Action GenerateTypeConstructorAction { get; set; } + + protected override void GenerateTypeConstructor(CodeTypeConstructor e) + { + GenerateTypeConstructorAction(e); + } + + public Action GenerateTypeEndAction { get; set; } + + protected override void GenerateTypeEnd(CodeTypeDeclaration e) + { + GenerateTypeEndAction(e); + } + + public Action> GenerateTypeOfExpressionAction { get; set; } + + protected override void GenerateTypeOfExpression(CodeTypeOfExpression e) + { + GenerateTypeOfExpressionAction(e, base.GenerateTypeOfExpression); + } + + public Action> GenerateTypeReferenceExpressionAction { get; set; } + + protected override void GenerateTypeReferenceExpression(CodeTypeReferenceExpression e) + { + GenerateTypeReferenceExpressionAction(e, base.GenerateTypeReferenceExpression); + } + + public Action GenerateTypeStartAction { get; set; } + + protected override void GenerateTypeStart(CodeTypeDeclaration e) + { + GenerateTypeStartAction(e); + } + + public Action GenerateVariableDeclarationStatementAction { get; set; } + + protected override void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e) + { + GenerateVariableDeclarationStatementAction(e); + } + + public Action GenerateVariableReferenceExpressionAction { get; set; } + + protected override void GenerateVariableReferenceExpression(CodeVariableReferenceExpression e) + { + GenerateVariableReferenceExpressionAction(e); + } + + public Func GetTypeOutputAction { get; set; } + + protected override string GetTypeOutput(CodeTypeReference value) + { + return GetTypeOutputAction(value); + } + + public Func IsValidIdentifierAction { get; set; } + + protected override bool IsValidIdentifier(string value) + { + return IsValidIdentifierAction(value); + } + + public Action> OutputAttributeArgumentAction { get; set; } + + protected override void OutputAttributeArgument(CodeAttributeArgument arg) + { + OutputAttributeArgumentAction(arg, base.OutputAttributeArgument); + } + + public Action> OutputAttributeDeclarationsAction { get; set; } + + protected override void OutputAttributeDeclarations(CodeAttributeDeclarationCollection attributes) + { + OutputAttributeDeclarationsAction(attributes, base.OutputAttributeDeclarations); + } + + public Action> OutputDirectionAction { get; set; } + + protected override void OutputDirection(FieldDirection dir) + { + OutputDirectionAction(dir, base.OutputDirection); + } + + public Action> OutputFieldScopeModifierAction { get; set; } + + protected override void OutputFieldScopeModifier(MemberAttributes attributes) + { + OutputFieldScopeModifierAction(attributes, base.OutputFieldScopeModifier); + } + + public Action> OutputIdentifierAction { get; set; } + + protected override void OutputIdentifier(string ident) + { + OutputIdentifierAction(ident, base.OutputIdentifier); + } + + public Action> OutputMemberAccessModifierAction { get; set; } + + protected override void OutputMemberAccessModifier(MemberAttributes attributes) + { + OutputMemberAccessModifierAction(attributes, base.OutputMemberAccessModifier); + } + + public Action> OutputMemberScopeModifierAction { get; set; } + + protected override void OutputMemberScopeModifier(MemberAttributes attributes) + { + OutputMemberScopeModifierAction(attributes, base.OutputMemberScopeModifier); + } + + public Action> OutputOperatorAction { get; set; } + + protected override void OutputOperator(CodeBinaryOperatorType op) + { + OutputOperatorAction(op, base.OutputOperator); + } + + public Action> OutputParametersAction { get; set; } + + protected override void OutputParameters(CodeParameterDeclarationExpressionCollection parameters) + { + OutputParametersAction(parameters, base.OutputParameters); + } + + public Action OutputTypeAction { get; set; } + + protected override void OutputType(CodeTypeReference typeRef) + { + OutputTypeAction(typeRef); + } + + public Action> OutputTypeAttributesAction { get; set; } + + protected override void OutputTypeAttributes(TypeAttributes attributes, bool isStruct, bool isEnum) + { + OutputTypeAttributesAction(attributes, isStruct, isEnum, base.OutputTypeAttributes); + } + + public Action> OutputTypeNamePairAction { get; set; } + + protected override void OutputTypeNamePair(CodeTypeReference typeRef, string name) + { + OutputTypeNamePairAction(typeRef, name, base.OutputTypeNamePair); + } + + public Func QuoteSnippetStringAction { get; set; } + + protected override string QuoteSnippetString(string value) + { + return QuoteSnippetStringAction(value); + } + + public Func SupportsAction { get; set; } + + protected override bool Supports(GeneratorSupport support) + { + return SupportsAction(support); + } + + public Action> ValidateIdentifierAction { get; set; } + + protected override void ValidateIdentifier(string value) + { + ValidateIdentifierAction(value, base.ValidateIdentifier); + } + + private class CustomCodeExpression : CodeExpression + { + } + + private class CustomCodeStatement : CodeStatement + { + } } }