/// <summary>
 /// Constructor.
 /// </summary>
 public JavaConstructorInvocationGenerator(
     JavaFileBuilder builder,
     IList<JavaClass> javaClasses)
 {
     _builder = builder;
     _javaClasses = javaClasses;
 }
		public void GenerateConstructorInvocation_GeneratesCorrectInvocation()
		{
			var question = new MethodQuestion();
			var fileBuilder = new JavaFileBuilder();

			var questionGenerator = GetQuestionGenerator(question);
			questionGenerator.GenerateConstructorInvocation(question, fileBuilder);

			Assert.Equal("ConstructorInvocation\n", fileBuilder.GetFileContents());
		}
        public void GenerateClassDefinition_GeneratesCorrectDefinition()
        {
            var javaClass = ExpectedJavaModel.GetFullJavaModel()
                .Single(c => c.ClassName == "RootObject");

            var fileBuilder = new JavaFileBuilder();
            var classDefGenerator = new JavaClassDefinitionGenerator(fileBuilder, javaClass);

            classDefGenerator.GenerateClassDefinition();

            var result = fileBuilder.GetFileContents();
            var expectedResult = c_correctDefinition.Replace("\r\n", "\n");

            Assert.Equal(expectedResult, result);
        }
		/// <summary>
		/// Generates an invocation of the question constructor that
		/// populates the resulting question with all of the existing 
		/// question's data.
		/// </summary>
		public void GenerateConstructorInvocation(
			Question existingQuestion,
			JavaFileBuilder fileBuilder)
		{
			var javaModel = _questionModelFactory.GetQuestionModel();

			var constructorInvocationGenerator = _javaCodeGenerationFactory
				.CreateConstructorInvocationGenerator(fileBuilder, javaModel);

			constructorInvocationGenerator.GenerateConstructorInvocation
			(
				existingQuestion,
				prefix: "return ",
				suffix: ";"
			);
		}
        public void GenerateConstructorInvocation_GeneratesCorrectInvocation()
        {
            var fileBuilder = new JavaFileBuilder();
            var javaModel = ExpectedJavaModel.GetFullJavaModel();
            var constructorInvocationGen = new JavaConstructorInvocationGenerator
            (
                fileBuilder,
                javaModel
            );

            constructorInvocationGen.GenerateConstructorInvocation
            (
                GetRootObject(),
                "return ",
                ";"
            );

            var result = fileBuilder.GetFileContents();
            var expectedResult = c_correctInvocation.Replace("\r\n", "\n");

            Assert.Equal(expectedResult, result);
        }
		/// <summary>
		/// Returns the contents of the file used to generate the question.
		/// </summary>
		private string GetGeneratorFile(int numImports, string generatorContents, out int lineOffset)
		{
			var fileBuilder = new JavaFileBuilder();
			var javaModel = _questionModelFactory.GetQuestionModel();

			foreach (var javaClass in javaModel)
			{
				var javaClassDefinitionGenerator = _javaCodeGenerationFactory
					.CreateJavaClassDefinitionGenerator(fileBuilder, javaClass);

				javaClassDefinitionGenerator.GenerateClassDefinition();
				fileBuilder.AddBlankLine();
			}

			lineOffset = -fileBuilder.LinesAdded - numImports;
			fileBuilder.AddLines(generatorContents);

			return fileBuilder.GetFileContents().Replace("%", "%%");
		}
		/// <summary>
		/// Returns a new generated question template based off of an existing question. 
		/// The generated question is not saved unless and until it is submitted through 
		/// CreateQuestionAsync.
		/// </summary>
		public async Task<Question> GenerateFromExistingQuestionAsync(
			string classroomName,
			int existingQuestionId)
		{
			var existingQuestion = await GetQuestionAsync(classroomName, existingQuestionId);

			if (existingQuestion is GeneratedQuestionTemplate)
			{
				throw new InvalidOperationException(
					"Cannot generate question from existing generated question.");
			}

			var builder = new JavaFileBuilder();

			builder.AddLine("public class QuestionGenerator");
			builder.BeginScope("{");
				builder.AddLine("public static Question generateQuestion(int seed)");
				builder.BeginScope("{");
					_questionGenerator.GenerateConstructorInvocation
					(
						existingQuestion,
						builder
					);
				builder.EndScope("}");
			builder.EndScope("}");

			return new GeneratedQuestionTemplate()
			{
				Name = $"{existingQuestion.Name} (generated)",
				QuestionCategoryId = existingQuestion.QuestionCategoryId,
				Description = "Generated Question",
				ImportedClasses = new List<ImportedClass>()
				{
					new ImportedClass()
					{
						ClassName = "java.util.*"
					}
				},
				GeneratorContents = builder.GetFileContents()
			};
		}
		/// <summary>
		/// Returns a mock java class definition generator.
		/// </summary>
		private static IJavaClassDefinitionGenerator GetMockJavaClassDefinitionGenerator(
			JavaFileBuilder builder,
			JavaClass javaClass)
		{
			var generator = new Mock<IJavaClassDefinitionGenerator>();

			generator
				.Setup
				(
					g => g.GenerateClassDefinition()
				)
				.Callback
				(
					() => builder.AddLine(javaClass.ClassName)
				);

			return generator.Object;
		}
		/// <summary>
		/// Returns a mock java constructor invocation generator.
		/// </summary>
		private static IJavaConstructorInvocationGenerator GetMockJavaConstructorInvocationGenerator(
			JavaFileBuilder builder,
			Question question)
		{
			var generator = new Mock<IJavaConstructorInvocationGenerator>();

			generator
				.Setup
				(
					g => g.GenerateConstructorInvocation
					(
						question,
						"return ",
						";"
					)
				)
				.Callback<object, string, string>
				(
					(obj, prefix, suffix) => builder.AddLine("ConstructorInvocation")
				);

			return generator.Object;
		}
 /// <summary>
 /// Creates a java class definition generator.
 /// </summary>
 public IJavaClassDefinitionGenerator CreateJavaClassDefinitionGenerator(
     JavaFileBuilder fileBuilder,
     JavaClass javaClass)
 {
     return new JavaClassDefinitionGenerator(fileBuilder, javaClass);
 }
 /// <summary>
 /// Creates a constructor invocation generator.
 /// </summary>
 public IJavaConstructorInvocationGenerator CreateConstructorInvocationGenerator(
     JavaFileBuilder fileBuilder,
     IList<JavaClass> javaClasses)
 {
     return new JavaConstructorInvocationGenerator(fileBuilder, javaClasses);
 }
 /// <summary>
 /// Constructor.
 /// </summary>
 public JavaClassDefinitionGenerator(JavaFileBuilder builder, JavaClass javaClass)
 {
     _builder = builder;
     _javaClass = javaClass;
 }