/// <summary>
        /// Метод, проверяющий валидность формулы
        /// </summary>
        /// <param name="formula"></param>
        /// <returns></returns>
        public bool Validate(ServerFormula formula)
        {
            if (string.IsNullOrWhiteSpace(formula?.FormulaString))
            {
                return(false);
            }

            var tokens = TokenDiscriminator.ConstructTokens(formula.FormulaString);

            if ((tokens?.Count ?? 0) == 0 || tokens.Any(t => t is UnknownToken))
            {
                return(false);
            }

            if (tokens.Any(token => token.Value == formula.Name)) //проверка на рекурсивную ссылку
            {
                return(false);
            }

            var bracketsIsValid = ValidateBrackets(tokens);

            if (!bracketsIsValid)
            {
                return(false);
            }

            var tokenSequenceIsValid = ValidateTokenSequence(tokens);

            if (!tokenSequenceIsValid)
            {
                return(false);
            }

            return(true);
        }
Example #2
0
        /// <summary>
        /// Асинхронный метод пересылки состояния. Добавляет пользователя в группу рассылки
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public async Task GetState(string name)
        {
            //достаем формулу из репозитория, чтобы убедиться, что такая вообще есть
            ServerFormula formula = null;

            using (AsyncScopedLifestyle.BeginScope(container))
                formula = await container.GetInstance <IRepository <ServerFormula> >().GetByNameAsync(name);

            if (formula is null)
            {
                Clients.Caller.SendError(name, "Формула не найдена или была окончательно удалена", DateTime.UtcNow);
            }
            else
            {
                //Добавляем в группу коннекшн и отправляем ему текущее состояние
                await Groups.Add(Context.ConnectionId, name);

                connectionGroups.AddOrUpdate(Context.ConnectionId,
                                             new List <string> {
                    name
                },
                                             (key, value) =>
                {
                    value.Add(name);
                    return(value);
                });

                Clients.Caller.SendState(formula.Name, formula.Status, DateTime.UtcNow);
            }
        }
        public async Task <IHttpActionResult> Post([FromBody][Bind(Include = "Name, FormulaString")] ServerFormula formula)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var existsformula = await repository.GetByNameAsync(formula.Name);

            if (existsformula != null)
            {
                return(Content(System.Net.HttpStatusCode.Conflict, "Такая формула уже существует"));
            }

            var success = await repository.CreateAsync(formula);

            if (success)
            {
                monitor.Created();
                return(Created("api/calculator", "Запрос на создание формулы успешно создан"));
            }
            else
            {
                return(InternalServerError(new Exception("Не удалось сохранить объект")));
            }
        }
        public async Task <IHttpActionResult> Update([FromBody][Bind(Include = "Name, FormulaString")] ServerFormula formula)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            var existsformula = await repository.GetByNameAsync(formula.Name);

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

            existsformula.FormulaString = formula.FormulaString;
            var success = await repository.UpdateAsync(existsformula);

            if (success)
            {
                monitor.Updated();
                return(Content(System.Net.HttpStatusCode.OK, "Запрос на обновление успешно создан"));
            }
            else
            {
                return(InternalServerError(new Exception("Не удалось обновить объект")));
            }
        }
Example #5
0
        public void Validate_WithNullStringTest()
        {
            //Arrange
            var formula = new ServerFormula();
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsFalse(isValid);
        }
Example #6
0
        public void Validate_NotValidSequenceTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "12 + - 10 * (5)"
            };
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsFalse(isValid);
        }
        /// <summary>
        /// Расчет значения формулы
        /// </summary>
        /// <param name="formula"></param>
        /// <returns></returns>
        public bool Calculate(ServerFormula formula, List <ServerFormula> requirments)
        {
            var tokens = TokenDiscriminator.Tokens ?? TokenDiscriminator.ConstructTokens(formula.FormulaString);

            tokens.CreateRPN();
            try
            {
                formula.Value = tokens.Calculate(requirments);
            }
            catch (DivideByZeroException) { throw; }
            catch { return(false); }
            return(true);
        }
Example #8
0
        public void ValidateRecursiveReferenceTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "(12 + 10) * (a)"
            };
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsFalse(isValid);
        }
Example #9
0
        public void Validate_NotValidBracketTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "(12 + 10)) * (5)"
            };
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsFalse(isValid);
        }
Example #10
0
        public void Validate_WithUnknownTokenTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "12 + - 10 * (5) + _a"
            };
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsFalse(isValid);
        }
Example #11
0
        public void ValidateSuccessTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "(12 + 10) * (c)"
            };
            //Act
            var isValid = validator.Validate(formula);

            //Assert
            Assert.IsTrue(isValid);
        }
Example #12
0
        public void CalculateTest()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "2 + 2"
            };
            //Act
            var success = calculator.Calculate(formula, new List <ServerFormula>());

            //Assert
            Assert.IsTrue(success);
        }
Example #13
0
        public void Calculate_WithNotEnoughRequirements()
        {
            //Arrange
            var formula = new ServerFormula()
            {
                Name = "a", FormulaString = "2 + b"
            };
            //Act
            var success = calculator.Calculate(formula, new List <ServerFormula>());

            //Assert
            Assert.IsFalse(success);
        }
Example #14
0
        public void Add_ValidationErrorTest()
        {
            //Arrange
            ServerFormula formula = new ServerFormula {
                FormulaString = null
            };

            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Post(formula).Result as ExceptionResult;

            //Assert
            Assert.IsNotNull(result);
        }
Example #15
0
        public INotifier ChangeStatus(ServerFormula formula, FormulaStatus newStatus)
        {
            if (formula is null)
            {
                throw new ArgumentNullException(nameof(formula));
            }

            formula.Status = newStatus;

            // Информация в обновлении
            info = new UpdateInfo(formula?.Name, newStatus);

            return(this);
        }
Example #16
0
        public void Delete_NotFoundTest()
        {
            //Arrange
            ServerFormula formula = new ServerFormula {
                FormulaString = null
            };

            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Update(formula).Result as NotFoundResult;

            //Assert
            Assert.IsNotNull(result);
        }
        public void ChangeStateTest()
        {
            //Arrange
            IFormulaStatusManager statusManager = new FormulaStatusManager();
            var formula = new ServerFormula()
            {
                Status = FormulaStatus.Success
            };
            var newStatus = FormulaStatus.Deleted;
            //Act
            var notifier = statusManager.ChangeStatus(formula, newStatus);

            //Assert
            Assert.AreEqual(newStatus, formula.Status);
            Assert.IsNotNull(notifier);
        }
Example #18
0
        public void Add_AlreadyExistsTest()
        {
            //Arrange
            ServerFormula formula = new ServerFormula {
                Name = "A", FormulaString = "5 + 5"
            };

            repository.Setup(r => r.GetByNameAsync(It.IsAny <string>())).Returns(Task.FromResult(formula));
            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Post(formula).Result as NegotiatedContentResult <string>;

            //Assert
            repository.Verify();
            Assert.IsNotNull(result);
        }
Example #19
0
        public void Delete_ErrorSaveTest()
        {
            //Arrange
            ServerFormula formula = new ServerFormula {
                Name = "A", FormulaString = "5 + 5"
            };

            repository.Setup(r => r.GetByNameAsync("A")).Returns(Task.FromResult(formula));
            repository.Setup(r => r.CreateAsync(formula)).Returns(Task.FromResult(false));
            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Delete(formula.Name).Result as ExceptionResult;

            //Assert
            repository.Verify();
            Assert.IsNotNull(result);
        }
Example #20
0
        public void AddTest()
        {
            //Arrange
            ServerFormula formula = new ServerFormula {
                Name = "A", FormulaString = "5 + 5"
            };

            repository.Setup(r => r.CreateAsync(formula)).Returns(Task.FromResult(true));
            monitor.Setup(m => m.Created());
            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Post(formula).Result as CreatedNegotiatedContentResult <string>;

            //Assert
            repository.Verify();
            Assert.IsNotNull(result);
            Assert.IsFalse(string.IsNullOrEmpty(result.Content));
        }
Example #21
0
 /// <summary>
 /// Вызывается когда все необходимые значения есть и остается только посчитать
 /// </summary>
 /// <param name="formula"></param>
 /// <param name="requireExistsFormula"></param>
 private void AllRequirementsReady(ServerFormula formula, IEnumerable <ServerFormula> requireExistsFormula)
 {
     foreach (var require in requireExistsFormula) //Добавляем ссылки на необходимые значения в базу
     {
         if (!formula.Required.Contains(require))
         {
             formula.Required.Add(require);
         }
     }
     try
     {
         formulaCalculator.Calculate(formula, requireExistsFormula.ToList()); // и Считаем
     }
     catch (DivideByZeroException)
     {
         statusManager.ChangeStatus(formula, FormulaStatus.DivideByZeroError);
     }
 }
Example #22
0
        public void GetWithIdTest()
        {
            //Arrange
            const int searchingId = 1;
            var       formula     = new ServerFormula()
            {
                FormulaId = searchingId
            };

            repository.Setup(r => r.GetByIdAsync(searchingId)).Returns(Task.FromResult(formula));
            controller = new CalculatorController(repository.Object, monitor.Object);
            //Act
            var result = controller.Get(searchingId).Result as JsonResult <ServerFormula>;
            var model  = result.Content;

            //Assert
            repository.Verify();
            Assert.IsNotNull(result);
            Assert.AreSame(formula, model);
        }
        /// <summary>
        /// Асинхронный метод расчета формул
        /// </summary>
        /// <param name="formula"></param>
        /// <returns></returns>
        public async Task CalculateAsync(ServerFormula formula, Func <Func <ServerFormula, bool>, Task <IEnumerable <ServerFormula> > > getSource)
        {
            bool     isCalculated       = false;
            DateTime startCalculateTime = DateTime.UtcNow;


            var tree = CreateTree(formula);

            // Если не будут получены все данные для расчета формулы в течение 10 минут,
            // то формула считается невалидной и не будет расчитана
            while (!isCalculated && (DateTime.UtcNow - startCalculateTime).TotalMinutes < 10)
            {
                isCalculated = await CalculateValue(tree, getSource);

                await Task.Delay(500);
            }

            if (!isCalculated)
            {
                formula.Status = FormulaStatus.Error;
            }
        }
Example #24
0
 /// <summary>
 /// Метод, проверяющий валидность формулы
 /// </summary>
 /// <param name="formula"></param>
 /// <returns></returns>
 public bool IsValid(ServerFormula formula)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Построение дерева выражения
 /// </summary>
 /// <param name="formula"></param>
 /// <returns></returns>
 private object CreateTree(ServerFormula formula)
 {
     throw new NotImplementedException();
 }