public void ParseExpression_UnexpectedSymbol_ThrowsParseExpressionException()
        {
            // Arrange
            var tokens = new Queue <Token>(new[]
            {
                // 1 $ 2
                new Token(new[] { '1' }, 1),
                new Token(new[] { '$' }),
                new Token(new[] { '2' }, 2),
                new Token(new[] { '\0' })
            });

            var tokenizerMock        = new Mock <ITokenizer>();
            var operationFactoryMock = new Mock <IOperationFactory>();
            var engine = new MathExpressionEngine(operationFactoryMock.Object);

            Token token = null;

            tokenizerMock.Setup(x => x.Init()).Callback(() => token      = tokens.Dequeue());
            tokenizerMock.Setup(x => x.NextToken()).Callback(() => token = tokens.Dequeue());
            tokenizerMock.SetupGet(x => x.CurrentToken).Returns(() => token);

            operationFactoryMock.Setup(x => x.IsSupportedOperation(It.IsAny <char>())).Returns(false);

            // Act
            Action result = () => engine.ParseExpression(tokenizerMock.Object);

            // Assert
            result.Should().Throw <ExpressionParseException>().WithMessage("Unexpected symbol: $");
        }
示例#2
0
        private static void Main()
        {
            while (true)
            {
                Console.WriteLine("Enter expression:");

                var expression = Console.ReadLine();

                if (string.IsNullOrEmpty(expression))
                {
                    continue;
                }

                if (expression.Equals("exit", StringComparison.OrdinalIgnoreCase))
                {
                    break;
                }

                try
                {
                    using var reader = new StringReader(expression);
                    var tokenizer        = new Tokenizer(reader);
                    var operationFactory = new OperationFactory();
                    var engine           = new MathExpressionEngine(operationFactory);

                    var result = engine.ParseExpression(tokenizer).Eval();

                    Console.WriteLine($"Your result: {result}");
                }
                catch (ExpressionParseException ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
        public void ParseExpression_ValidExpression_ReturnsParsedResult()
        {
            // Arrange
            var tokens = new Queue <Token>(new[]
            {
                // -((10 + 20) - 5 * 5 + 2 * 2)
                new Token(new[] { '-' }),
                new Token(new[] { '(' }),
                new Token(new[] { '(' }),
                new Token(new[] { '1', '0' }, 10),
                new Token(new[] { '+' }),
                new Token(new[] { '2', '0' }, 20),
                new Token(new[] { ')' }),
                new Token(new[] { '-' }),
                new Token(new[] { '5' }, 5),
                new Token(new[] { '*' }),
                new Token(new[] { '5' }, 5),
                new Token(new[] { '+' }),
                new Token(new[] { '2' }, 2),
                new Token(new[] { '*' }),
                new Token(new[] { '2' }, 2),
                new Token(new[] { ')' }),
                new Token(new[] { '\0' })
            });

            var tokenizerMock        = new Mock <ITokenizer>();
            var operationFactoryMock = new Mock <IOperationFactory>();
            var engine = new MathExpressionEngine(operationFactoryMock.Object);

            Token token = null;

            tokenizerMock.Setup(x => x.Init()).Callback(() => token      = tokens.Dequeue());
            tokenizerMock.Setup(x => x.NextToken()).Callback(() => token = tokens.Dequeue());
            tokenizerMock.SetupGet(x => x.CurrentToken).Returns(() => token);

            operationFactoryMock.Setup(x => x.IsSupportedOperation(It.IsAny <char>())).Returns(true);
            operationFactoryMock.Setup(x => x.CreateLowPriorityOperation('+')).Returns((a, b) => a + b);
            operationFactoryMock.Setup(x => x.CreateLowPriorityOperation('-')).Returns((a, b) => a - b);
            operationFactoryMock.Setup(x => x.CreateHighPriorityOperation('*')).Returns((a, b) => a * b);

            // Act
            var result = engine.ParseExpression(tokenizerMock.Object).Eval();

            // Assert
            result.Should().Be(-9);
        }