/// <summary>
        /// Verifies that the given code question was correctly duplicated.
        /// </summary>
        private void VerifyCodeQuestion(
            DatabaseContext dbContext,
            CodeQuestion oldQuestion,
            CodeQuestion newQuestion)
        {
            VerifyCollectionDuplicated
            (
                dbContext,
                oldQuestion,
                newQuestion,
                q => q.ImportedClasses,
                c => c.Id,
                c => c.ClassName
            );

            VerifyCollectionDuplicated
            (
                dbContext,
                oldQuestion,
                newQuestion,
                q => q.CodeConstraints,
                c => c.Id,
                c => c.Regex
            );
        }
 /// <summary>
 /// Creates a new code question updater.
 /// </summary>
 private static CodeQuestionUpdater <CodeQuestion> GetCodeQuestionUpdater(
     TestDatabase database,
     CodeQuestion question,
     IModelErrorCollection errors)
 {
     return(new Mock <CodeQuestionUpdater <CodeQuestion> >(database.Context, question, errors).Object);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns a code question grader. For a given question, the grader
        /// returns a given simulated result for a given submission.
        /// </summary>
        public CodeQuestionGrader <CodeQuestion> GetCodeQuestionGrader(
            CodeQuestion question,
            CodeQuestionSubmission submission,
            CodeJobResult simulatedResult,
            IList <DefinitionError> definitionErrors = null)
        {
            var grader = new Mock <CodeQuestionGrader <CodeQuestion> >
                         (
                question,
                null                 /*codeRunnerService*/
                         );

            grader.CallBase = true;

            grader.Protected()
            .Setup <Task <CodeJobResult> >
            (
                "ExecuteJobAsync",
                ItExpr.Is <CodeQuestionSubmission>(s => s == submission)
            ).Returns(Task.FromResult(simulatedResult));

            grader.Protected()
            .Setup <string>("GetTestDescription", ItExpr.IsAny <CodeQuestionTest>())
            .Returns <CodeQuestionTest>(test => test.Name);

            if (definitionErrors != null)
            {
                grader.Protected()
                .Setup <IEnumerable <CodeQuestionError> >
                (
                    "GetDefinitionErrors",
                    ItExpr.Is <CodeQuestionSubmission>(s => s == submission),
                    ItExpr.Is <CodeJobResult>(r => r == simulatedResult)
                ).Returns(definitionErrors);
            }

            return(grader.Object);
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Creates a new mock question duplicator.
 /// </summary>
 private static CodeQuestionDuplicator <CodeQuestion> GetCodeQuestionDuplicator(
     TestDatabase database,
     CodeQuestion question)
 {
     return(new Mock <CodeQuestionDuplicator <CodeQuestion> >(database.Context, question).Object);
 }
Ejemplo n.º 5
0
        public async Task <IActionResult> AddCodeQuestion([FromBody] AddCodeQuestionViewModel model)
        {
            var user = await _userManager.GetUserAsync(HttpContext.User);

            var test = await _context.Tests.SingleOrDefaultAsync(t => t.Id == (int)RouteData.Values["testId"]);

            if (test == null)
            {
                return(NotFound());
            }

            if (test.CreatedBy != user)
            {
                return(Forbid());
            }
            model.TestId = test.Id;
            TryValidateModel(model);
            if (ModelState.IsValid)
            {
                using (var ts = _context.Database.BeginTransaction())
                {
                    var question = new CodeQuestion
                    {
                        Title        = model.Title,
                        QuestionType = Enum.GetName(typeof(Question.QuestionTypeEnum), 5),
                        Test         = test,
                        Score        = model.Score
                    };
                    question = (await _context.AddAsync(question)).Entity;
                    await _context.SaveChangesAsync();

                    var co = new Code
                    {
                        Args     = model.Code.Args,
                        Question = question,
                        Value    = model.Code.Value
                    };
                    var code = (await _context.AddAsync(
                                    new Code
                    {
                        Args = model.Code.Args,
                        Question = question,
                        Value = model.Code.Value,
                        Output = Compile(co)
                    })).Entity;
                    await _context.AddAsync(
                        new Option { Text = model.Code.Output, Question = question });

                    question.Code = code;
                    try
                    {
                        _context.Remove(await _context.Codes.SingleAsync(c => c.Test == test));
                    }
                    catch
                    {
                    }

                    _context.Questions.Update(question);
                    await _context.SaveChangesAsync();

                    ts.Commit();
                }

                var redirectUrl = Url.Action("Details", "Test", new { id = test.Id });
                return(new JsonResult(redirectUrl));
            }

            var errors = new List <ModelError>();

            foreach (var modelState in ViewData.ModelState.Values)
            {
                foreach (var error in modelState.Errors)
                {
                    errors.Add(error);
                }
            }
            Response.StatusCode = StatusCodes.Status400BadRequest;
            return(new JsonResult(errors));
        }
Ejemplo n.º 6
0
            private static void ParseQuestion(Queue <Token> tokens, Test test, TestData testData)
            {
                Question question;
                int      i = 1, checkedCount = 0, Row = 0;
                bool     textParsed = false, scoreParsed = false, optionParsed = false, codeParsed = false;

                Row = tokens.Peek().Row;
                Consume(tokens, "question");
                Consume(tokens, "{");
                var type = ParseType(tokens);

                switch (type)
                {
                case (int)Question.QuestionTypeEnum.SingleChoiceQuestion:
                    question = new SingleChoiceQuestion();
                    break;

                case (int)Question.QuestionTypeEnum.MultiChoiceQuestion:
                    question = new MultiChoiceQuestion();
                    break;

                case (int)Question.QuestionTypeEnum.TextQuestion:
                    question = new TextQuestion();
                    break;

                case (int)Question.QuestionTypeEnum.DragAndDropQuestion:
                    question = new DragAndDropQuestion();
                    break;

                case (int)Question.QuestionTypeEnum.CodeQuestion:
                    question = new CodeQuestion();
                    break;

                default:
                    question = new SingleChoiceQuestion();
                    break;
                }

                question.Test = test;
                while (tokens.Peek().Value != "}")
                {
                    switch (tokens.Peek().Value)
                    {
                    case "text":
                        if (!textParsed)
                        {
                            question.Title = ParseString(tokens, "text");
                        }
                        else
                        {
                            throw new Exception(string.Format("Text already parsed (Quesiton (Row - {0})).", Row));
                        }
                        textParsed = true;
                        break;

                    case "score":
                        if (!scoreParsed)
                        {
                            question.Score = ParseInt(tokens, "score");
                        }
                        else
                        {
                            throw new Exception(string.Format("Score already parsed (Quesiton (Row - {0})).", Row));
                        }
                        scoreParsed = true;
                        break;

                    case "option":
                        if (question is TextQuestion)
                        {
                            if (i == 1)
                            {
                                ParseOption(tokens, question, testData, i++, ref checkedCount);
                            }
                            else
                            {
                                throw new Exception(string.Format(
                                                        "TextQuestion поддерживает только один ответ (Quesiton (Row - {0})).", Row));
                            }
                        }
                        else
                        {
                            ParseOption(tokens, question, testData, i++, ref checkedCount);
                        }
                        optionParsed = true;
                        break;

                    case "code":
                        if (question is CodeQuestion)
                        {
                            if (!codeParsed)
                            {
                                ParseCode(tokens, question, testData);
                            }
                            else
                            {
                                throw new Exception(string.Format(
                                                        "CodeQuestion поддерживает только один ответ (Quesiton (Row - {0})).", Row));
                            }
                        }
                        else
                        {
                            throw new Exception(
                                      string.Format("Данный тип вопроса не поддерживает code(Quesiton (Row - {0})).",
                                                    Row));
                        }

                        codeParsed = true;
                        break;

                    default:
                        throw new Exception(string.Format("Неизвестный параметр: {0} (Row - {1}).",
                                                          tokens.Peek().Value, tokens.Peek().Row));
                    }
                }
                question.QuestionType = Enum.GetName(typeof(Question.QuestionTypeEnum), type);
                if (question is SingleChoiceQuestion && checkedCount != 1)
                {
                    throw new Exception(string.Format(
                                            "В данном типе вопроса нужно отметить верный один ответ (Quesiton (Row - {0})).", Row));
                }
                if (question is MultiChoiceQuestion && checkedCount < 1)
                {
                    throw new Exception(string.Format(
                                            "В данном типе вопроса нужно отметить хотя бы один верный ответ (Quesiton (Row - {0})).", Row));
                }
                Consume(tokens, "}");
                if (!scoreParsed)
                {
                    question.Score = 1;
                }
                if (!(question is CodeQuestion))
                {
                    if (!textParsed || !optionParsed)
                    {
                        throw new Exception(string.Format(
                                                "Заданы не все требуемые поля (Quesiton (Row - {0})). Text - {1}, Option - {2}.",
                                                Row, textParsed, optionParsed));
                    }
                }
                else if (!textParsed || !codeParsed)
                {
                    throw new Exception(string.Format(
                                            "Заданы не все требуемые поля (Quesiton (Row - {0})). Text - {1}, Code - {2}.",
                                            Row, textParsed, codeParsed));
                }

                testData.Questions.Add(question);
            }