context: //
  // StronglyTypedResourceBuilderNamespaceTests.cs - tests the 
  // generatedCodeNamespace and resourcesNamespace params of the main 
  // Create overload
  // 
  // Author:
  //	Gary Barnett (gary.barnett.mono@gmail.com)
  // 
  // Copyright (C) Gary Barnett (2012)
  //
  //
  // Permission is hereby granted, free of charge, to any person obtaining
  // a copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to
  // permit persons to whom the Software is furnished to do so, subject to
  // the following conditions:
  // 
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  //
  
  using NUnit.Framework;
  using System;
  using System.Resources.Tools;
  using System.CodeDom;
  using Microsoft.CSharp;
  using System.Collections.Generic;
  
  namespace MonoTests.System.Resources.Tools {
  	[TestFixture]
  	public class StronglyTypedResourceBuilderNamespaceTests	{
  		static string [] keywords = {"abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", 
  					"checked", "class", "const", "continue", "decimal", "default", "delegate", 
  					"do", "double", "else", "enum", "event", "explicit", "extern", "FALSE", 
  					"false", "finally", "fixed", "float", "for", "foreach", "goto", "if", 
  					"implicit", "in", "int", "interface", "internal", "is", "lock", "long", 
  					"namespace", "new", "null", "object", "operator", "out", "override", "params", 
  					"private", "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", 
  					"short", "sizeof", "stackalloc", "static", "string", "struct", "switch", "this", 
  					"throw", "TRUE", "true", "try", "typeof", "uint", "ulong", "unchecked", "unsafe", 
  					"ushort", "using", "virtual", "volatile", "void", "while" };
  		static char [] specialChars = { ' ', '\u00A0', '.', ',', ';', '|', '~', '@', '#', '%', '^', '&', 
  					'*', '+', '-', '/', '\\', '<', '>', '?', '[', ']', '(', ')', '{', 
  					'}', '\"', '\'', ':', '!'};
  		CSharpCodeProvider provider = new CSharpCodeProvider ();
  		Dictionary<string, object> testResources;
  		
  		[SetUp]
  		public void Setup ()
  		{
  			testResources = new Dictionary<string, object> ();
  			testResources.Add ("akey", String.Empty);
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceEmpty ()
  		{
  			// empty namespace allowed
  			string [] unmatchables;
  			string input, expected;
  			CodeCompileUnit ccu;
  			
  			input = String.Empty;
  			
  			expected = String.Empty;
  			
  			ccu = StronglyTypedResourceBuilder.Create (testResources,
  								"TestClass",
  								input,
  								"TestResourceNameSpace",
  								provider,
  								true,
  								out unmatchables);
  			
  			Assert.AreEqual (expected,ccu.Namespaces [0].Name);
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceNull ()
  		{
  			// null should be replaced with String.Empty
  			string [] unmatchables;
  			string input, expected;
  			CodeCompileUnit ccu;
  			
  			input = null;
  			
  			expected = String.Empty;
  			
  			ccu = StronglyTypedResourceBuilder.Create (testResources,
  								"TestClass",
  								input,
  								"TestResourceNameSpace",
  								provider,
  								true,
  								out unmatchables);
  			
  			Assert.AreEqual (expected,ccu.Namespaces [0].Name);
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceProviderInvalidIdentifiersOK ()
  		{
  			// identifiers which are still invalid after CreateValidIdentifier called allowed through in .NET framework
  			string [] unmatchables;
  			string input, output, expected;
  			CodeCompileUnit ccu;
  			
  			input = "te$st";
  			expected = "te$st";
  			
  			ccu = StronglyTypedResourceBuilder.Create (testResources,
  								"TestClass",
  								input,
  								"TestResourcesNameSpace",
  								provider,
  								true,
  								out unmatchables);
  			
  			output = ccu.Namespaces [0].Name;
  			
  			Assert.AreEqual (expected,output);
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceProviderKeywords ()
  		{
  			string expected;
  			string [] unmatchables;
  			CodeCompileUnit ccu;
  
  			foreach (string input in keywords) {
  				ccu = StronglyTypedResourceBuilder.Create (testResources,
  									"TestClass",
  									input,
  									"TestResourcesNameSpace",
  									provider,
  									true,
  									out unmatchables);
  				
  				expected = provider.CreateValidIdentifier (input);
  				
  				Assert.AreEqual (expected,ccu.Namespaces [0].Name);
  			}
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceProviderKeywordsMultipart ()
  		{
  			// .NET framework does not check individiual elements of multipart namespace
  			string expected, input;
  			string [] unmatchables;
  			CodeCompileUnit ccu;
  			
  			foreach (string word in keywords) {
  				
  				input = "Primary." + word;
  				
  				ccu = StronglyTypedResourceBuilder.Create (testResources,
  									"TestClass",
  									input,
  									"TestResourcesNameSpace",
  									provider,
  									true,
  									out unmatchables);
  				
  				expected = provider.CreateValidIdentifier (input);
  				
  				Assert.AreEqual (expected,ccu.Namespaces [0].Name);
  			}
  		}
  		
  		[Test]
  		public void GeneratedCodeNamespaceSpecialChars ()
  		{
  			// invalid chars replaced with _ noting (. and :) are allowed by .NET framework
  			string [] unmatchables;
  			string input, output, expected;
  			
  			CodeCompileUnit ccu;
  			
  			foreach (char c in specialChars) {
  				input = "test" + c.ToString ();
  				
  				if (c == '.' || c == ':')
  					expected = input;
  				else
  					expected = StronglyTypedResourceBuilder.VerifyResourceName(input, provider);
  			
  				ccu = StronglyTypedResourceBuilder.Create (testResources,
  									"TestClass",
  									input,
  									"TestResourcesNameSpace",
  									provider,
  									true,
  									out unmatchables);
  				
  				output = ccu.Namespaces [0].Name;
  				
  				Assert.AreEqual (expected,output);
  			}
  		}
  		
  		[Test]
  		public void ResourcesNamespaceEmpty ()
  		{
  			// when ResourcesNamespace is String.Empty no namespace is used
  			string [] unmatchables;
  			string input, output, expected;
  			CodeCompileUnit ccu;
  			CodeMemberProperty resourceManager;
  			CodeVariableDeclarationStatement cvds;
  			
  			input = String.Empty;
  			
  			expected = "TestClass";
  			
  			ccu = StronglyTypedResourceBuilder.Create (testResources,
  								"TestClass",
  								"TestNameSpace",
  								input,
  								provider,
  								true,
  								out unmatchables);
  			
  			resourceManager = StronglyTypedResourceBuilderCodeDomTest.Get<CodeMemberProperty> (
  													"ResourceManager", ccu);
  			cvds = ((CodeVariableDeclarationStatement)((CodeConditionStatement)resourceManager.GetStatements [0]).TrueStatements [0]);
  			output  = ((CodePrimitiveExpression)((CodeObjectCreateExpression)cvds.InitExpression).Parameters [0]).Value.ToString ();
  			
  			Assert.AreEqual (expected,output);
  		}
  		
  		[Test]
  		public void ResourcesNamespaceNull ()
  		{
  			// when ResourcesNamespace is null generatedCodeNamespace is used in its place
  			string[] unmatchables;
  			string input, output, expected;
  			CodeCompileUnit ccu;
  			CodeMemberProperty resourceManager;
  			CodeVariableDeclarationStatement cvds;
  			
  			input = null;
  			
  			expected = "TestNameSpace.TestClass";
  			
  			ccu = StronglyTypedResourceBuilder.Create (testResources,
  								"TestClass",
  								"TestNameSpace",
  								input,
  								provider,
  								true,
  								out unmatchables);
  			
  			resourceManager = StronglyTypedResourceBuilderCodeDomTest.Get<CodeMemberProperty> (
  													"ResourceManager", ccu);
  			cvds = ((CodeVariableDeclarationStatement)((CodeConditionStatement)resourceManager.GetStatements [0]).TrueStatements [0]);
  			output  = ((CodePrimitiveExpression)((CodeObjectCreateExpression)cvds.InitExpression).Parameters [0]).Value.ToString ();
  			
  			Assert.AreEqual (expected,output);
  		}
  
  		[Test]
  		public void ResourcesNamespaceProviderKeywords ()
  		{
  			// not validated against provider keywords in .net framework
  			string output,expected;
  			string [] unmatchables;
  			CodeCompileUnit ccu;
  			CodeMemberProperty resourceManager;
  			CodeVariableDeclarationStatement cvds;
  			
  			foreach (string input in keywords) {
  				ccu = StronglyTypedResourceBuilder.Create (testResources,
  									"TestClass",
  									"TestNamespace",
  									input,
  									provider,
  									true,
  									out unmatchables);
  
  				expected = input + ".TestClass";
  				resourceManager = StronglyTypedResourceBuilderCodeDomTest.Get<CodeMemberProperty> (
  													"ResourceManager", ccu);
  				cvds = ((CodeVariableDeclarationStatement)((CodeConditionStatement)resourceManager.GetStatements [0]).TrueStatements [0]);
  				output  = ((CodePrimitiveExpression)((CodeObjectCreateExpression)cvds.InitExpression).Parameters [0]).Value.ToString ();
  				
  				Assert.AreEqual (expected,output);
  			}
  		}
  		
  		[Test]
  		public void ResourcesNamespaceSpecialChars ()
  		{
  			// ResourcesNamespace doesnt seem to be validated at all in .NET framework
  			string [] unmatchables;
  			string input, output, expected;
  			CodeCompileUnit ccu;
  			CodeMemberProperty resourceManager;
  			CodeVariableDeclarationStatement cvds;
  			
  			foreach (char c in specialChars) {
  				input = "test" + c.ToString ();
  				
  
gt: 				expected = input + ".TestClass";