2020using System . Collections . Generic ;
2121using System . Linq ;
2222using ICSharpCode . NRefactory . TypeSystem ;
23- using ICSharpCode . PackageManagement ;
2423using ICSharpCode . PackageManagement . EnvDTE ;
25- using ICSharpCode . SharpDevelop . Dom ;
2624using NUnit . Framework ;
2725using PackageManagement . Tests . Helpers ;
2826using Rhino . Mocks ;
@@ -33,24 +31,54 @@ namespace PackageManagement.Tests.EnvDTE
3331 public class CodeClass2Tests : CodeModelTestBase
3432 {
3533 CodeClass2 codeClass ;
34+ ITypeDefinition codeClassTypeDefinition ;
3635
37- void CreateClass ( string code )
36+ ITypeDefinition addFieldAtStartTypeDef ;
37+ Accessibility addFieldAtStartAccess ;
38+ IType addFieldAtStartReturnType ;
39+ string addFieldAtStartName ;
40+
41+ void CreateClass ( string code , string fileName = @"c:\projects\MyProject\class.cs" )
3842 {
39- AddCodeFile ( "class.cs" , code ) ;
43+ CreateCodeModel ( ) ;
44+ AddCodeFile ( fileName , code ) ;
4045 ITypeDefinition typeDefinition = GetFirstTypeDefinition ( ) ;
4146 CreateClass ( typeDefinition ) ;
4247 }
4348
49+ void UpdateCode ( string code , string fileName = @"c:\projects\MyProject\class.cs" )
50+ {
51+ CreateCompilationForUpdatedCodeFile ( fileName , code ) ;
52+ }
53+
4454 ITypeDefinition GetFirstTypeDefinition ( )
4555 {
4656 return assemblyModel . TopLevelTypeDefinitions . First ( ) . Resolve ( ) ;
4757 }
4858
4959 void CreateClass ( ITypeDefinition typeDefinition )
5060 {
61+ codeClassTypeDefinition = typeDefinition ;
5162 codeClass = new CodeClass2 ( codeModelContext , typeDefinition ) ;
5263 }
5364
65+ void CaptureCodeGeneratorAddFieldAtStartParameters ( )
66+ {
67+ codeGenerator
68+ . Stub ( generator => generator . AddFieldAtStart (
69+ Arg < ITypeDefinition > . Is . Anything ,
70+ Arg < Accessibility > . Is . Anything ,
71+ Arg < IType > . Is . Anything ,
72+ Arg < string > . Is . Anything ) )
73+ . Callback < ITypeDefinition , Accessibility , IType , string > ( ( typeDef , access , type , name ) => {
74+ addFieldAtStartTypeDef = typeDef ;
75+ addFieldAtStartAccess = access ;
76+ addFieldAtStartReturnType = type ;
77+ addFieldAtStartName = name ;
78+ return true ;
79+ } ) ;
80+ }
81+
5482 [ Test ]
5583 public void Language_CSharpProject_ReturnsCSharpModelLanguage ( )
5684 {
@@ -405,5 +433,92 @@ public void Members_ClassIsSystemAttributeAsReturnTypeFromClassMethod_HasMembers
405433 Assert . That ( members . Count , Is . GreaterThan ( 0 ) ) ;
406434 Assert . IsTrue ( members . Any ( member => member . Name == "IsDefaultAttribute" ) ) ;
407435 }
436+
437+ [ Test ]
438+ public void AddVariable_PublicSystemInt32Variable_AddsFieldWithCodeConverter ( )
439+ {
440+ CreateClass ( "class MyClass {}" ) ;
441+ var access = global ::EnvDTE . vsCMAccess . vsCMAccessPublic ;
442+ CaptureCodeGeneratorAddFieldAtStartParameters ( ) ;
443+ string newCode =
444+ "class MyClass {\r \n " +
445+ " public System.Int32 MyField;\r \n " +
446+ "}" ;
447+ UpdateCode ( newCode ) ;
448+
449+ codeClass . AddVariable ( "MyField" , "System.Int32" , null , access , null ) ;
450+
451+ Assert . AreEqual ( Accessibility . Public , addFieldAtStartAccess ) ;
452+ Assert . AreEqual ( "MyField" , addFieldAtStartName ) ;
453+ Assert . AreEqual ( codeClassTypeDefinition , addFieldAtStartTypeDef ) ;
454+ Assert . AreEqual ( "System.Int32" , addFieldAtStartReturnType . FullName ) ;
455+ Assert . IsTrue ( addFieldAtStartReturnType . IsKnownType ( KnownTypeCode . Int32 ) ) ;
456+ }
457+
458+ [ Test ]
459+ public void AddVariable_PrivateVariableOfUnknownType_AddsFieldWithCodeConverter ( )
460+ {
461+ CreateClass ( "class MyClass {}" ) ;
462+ var access = global ::EnvDTE . vsCMAccess . vsCMAccessPrivate ;
463+ CaptureCodeGeneratorAddFieldAtStartParameters ( ) ;
464+ string newCode =
465+ "class MyClass {\r \n " +
466+ " Unknown.UnknownClass MyField;\r \n " +
467+ "}" ;
468+ UpdateCode ( newCode ) ;
469+
470+ codeClass . AddVariable ( "MyField" , "Unknown.UnknownClass" , null , access , null ) ;
471+
472+ Assert . AreEqual ( Accessibility . Private , addFieldAtStartAccess ) ;
473+ Assert . AreEqual ( "MyField" , addFieldAtStartName ) ;
474+ Assert . AreEqual ( codeClassTypeDefinition , addFieldAtStartTypeDef ) ;
475+ Assert . AreEqual ( "Unknown.UnknownClass" , addFieldAtStartReturnType . FullName ) ;
476+ }
477+
478+ [ Test ]
479+ public void AddVariable_PublicSystemInt32Variable_ReturnsCodeVariableForField ( )
480+ {
481+ string fileName = @"c:\projects\MyProject\class.cs" ;
482+ CreateClass ( "class MyClass {}" , fileName ) ;
483+ var access = global ::EnvDTE . vsCMAccess . vsCMAccessPublic ;
484+ string newCode =
485+ "class MyClass {\r \n " +
486+ " public int MyField;\r \n " +
487+ "}" ;
488+ UpdateCode ( newCode , fileName ) ;
489+
490+ var codeVariable = codeClass . AddVariable ( "MyField" , "System.Int32" , null , access , null ) as CodeVariable ;
491+
492+ Assert . AreEqual ( "MyField" , codeVariable . Name ) ;
493+ }
494+
495+ [ Test ]
496+ public void AddVariable_FieldNotFoundAfterReloadingTypeDefinition_ReturnsNull ( )
497+ {
498+ string fileName = @"c:\projects\MyProject\class.cs" ;
499+ CreateClass ( "class MyClass {}" , fileName ) ;
500+ var access = global ::EnvDTE . vsCMAccess . vsCMAccessPublic ;
501+ string newCode = "class MyClass {}" ;
502+ UpdateCode ( newCode , fileName ) ;
503+
504+ var codeVariable = codeClass . AddVariable ( "MyField" , "System.Int32" , null , access , null ) as CodeVariable ;
505+
506+ Assert . IsNull ( codeVariable ) ;
507+ }
508+
509+ [ Test ]
510+ public void AddVariable_UnableToFindTypeDefinitionAfterUpdate_ReturnsNull ( )
511+ {
512+ string fileName = @"c:\projects\MyProject\class.cs" ;
513+ CreateClass ( "class MyClass {}" , fileName ) ;
514+ var access = global ::EnvDTE . vsCMAccess . vsCMAccessPublic ;
515+ string newCode = "class MyClass {}" ;
516+ UpdateCode ( newCode , fileName ) ;
517+
518+ var codeVariable = codeClass . AddVariable ( "MyField" , "System.Int32" , null , access , null ) as CodeVariable ;
519+
520+ Assert . IsNull ( codeVariable ) ;
521+ Assert . AreEqual ( "MyClass" , codeClass . Name ) ;
522+ }
408523 }
409524}
0 commit comments