<commit_before>﻿using System;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Tree;
using AutoMoq.Helpers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using ProjectHekate.Grammar.Implementation;
using ProjectHekate.Scripting;

namespace ProjectHekate.Grammar.Tests
{
    [TestClass]
    public class THekateScriptVisitor : AutoMoqTestFixture<HekateScriptVisitor>
    {
        protected const string WrappedProgramStringUnfmted = "function main(){{{0};}}";

        protected virtual TContextType GenerateContext<TContextType>(string expression) where TContextType : class, IParseTree
        {
            var lexer = new HekateLexer(new AntlrInputStream(String.Format(WrappedProgramStringUnfmted, expression)));
            var tokens = new CommonTokenStream(lexer);
            var parser = new HekateParser(tokens);

            var tree = parser.script();

            return tree.GetFirstDescendantOfType<TContextType>();
        }

        [TestClass]
        public class VisitBinaryExpression : THekateScriptVisitor
        {
            [TestClass]
            public class Addition : VisitBinaryExpression
            {
                [TestMethod]
                public void ShouldGenerateCodeForBasicExpression()
                {
                    // Setup: dummy data + mock vm out
                    const string expression = "3+5";

                    ResetSubject();

                    // Act
                    var result = Subject.VisitBinaryExpression(GenerateContext<HekateParser.BinaryExpressionContext>(expression));

                    // Verify
                    result.Code.Should().HaveCount(5);
                    result.Code[0].Should().Be((byte)Instruction.Push);
                    result.Code[1].Should().Be(3);
                    result.Code[2].Should().Be((byte)Instruction.Push);
                    result.Code[3].Should().Be(5);
                    result.Code[4].Should().Be((byte)Instruction.OperatorAdd);
                }

                [TestMethod]
                public void ShouldGenerateCodeForComplexExpression()
                {
                    // Setup: dummy data + mock vm out
                    const string expression = "(3+5)+7";

                    ResetSubject();

                    // Act
                    var result = Subject.VisitBinaryExpression(GenerateContext<HekateParser.BinaryExpressionContext>(expression));

                    // Verify
                    result.Code.Should().HaveCount(8);
                    result.Code[0].Should().Be((byte)Instruction.Push);
                    result.Code[1].Should().Be(3);
                    result.Code[2].Should().Be((byte)Instruction.Push);
                    result.Code[3].Should().Be(5);
                    result.Code[4].Should().Be((byte)Instruction.OperatorAdd);
                    result.Code[5].Should().Be((byte)Instruction.Push);
                    result.Code[6].Should().Be(7);
                    result.Code[7].Should().Be((byte)Instruction.OperatorAdd);
                }
            }
        }
<commit_msg>Renames a test and adds a new test for a more complex expression.<commit_after>﻿using System;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Tree;
using AutoMoq.Helpers;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using ProjectHekate.Grammar.Implementation;
using ProjectHekate.Scripting;

namespace ProjectHekate.Grammar.Tests
{
    [TestClass]
    public class THekateScriptVisitor : AutoMoqTestFixture<HekateScriptVisitor>
    {
        protected const string WrappedProgramStringUnfmted = "function main(){{{0};}}";

        protected virtual TContextType GenerateContext<TContextType>(string expression) where TContextType : class, IParseTree
        {
            var lexer = new HekateLexer(new AntlrInputStream(String.Format(WrappedProgramStringUnfmted, expression)));
            var tokens = new CommonTokenStream(lexer);
            var parser = new HekateParser(tokens);

            var tree = parser.script();

            return tree.GetFirstDescendantOfType<TContextType>();
        }

        [TestClass]
        public class VisitBinaryExpression : THekateScriptVisitor
        {
            [TestClass]
            public class Addition : VisitBinaryExpression
            {
                [TestMethod]
                public void ShouldGenerateCodeForBasicExpression()
                {
                    // Setup: dummy data + mock vm out
                    const string expression = "3+5";

                    ResetSubject();

                    // Act
                    var result = Subject.VisitBinaryExpression(GenerateContext<HekateParser.BinaryExpressionContext>(expression));

                    // Verify
                    result.Code.Should().HaveCount(5);
                    result.Code[0].Should().Be((byte)Instruction.Push);
                    result.Code[1].Should().Be(3);
                    result.Code[2].Should().Be((byte)Instruction.Push);
                    result.Code[3].Should().Be(5);
                    result.Code[4].Should().Be((byte)Instruction.OperatorAdd);
                }

                [TestMethod]
                public void ShouldGenerateCodeForExpressionIncludingSingleParenthesizedExpression()
                {
                    // Setup: dummy data + mock vm out
                    const string expression = "(3+5)+7";

                    ResetSubject();

                    // Act
                    var result = Subject.VisitBinaryExpression(GenerateContext<HekateParser.BinaryExpressionContext>(expression));

                    // Verify
                    result.Code.Should().HaveCount(8);
                    result.Code[0].Should().Be((byte)Instruction.Push);
                    result.Code[1].Should().Be(3);
                    result.Code[2].Should().Be((byte)Instruction.Push);
                    result.Code[3].Should().Be(5);
                    result.Code[4].Should().Be((byte)Instruction.OperatorAdd);
                    result.Code[5].Should().Be((byte)Instruction.Push);
                    result.Code[6].Should().Be(7);
                    result.Code[7].Should().Be((byte)Instruction.OperatorAdd);
                }


                [TestMethod]
                public void ShouldGenerateCodeForComplexExpression()
                {
                    // Setup: dummy data + mock vm out
                    const string expression = "-35+((3+5)+7)";

                    ResetSubject();

                    // Act
                    var result = Subject.VisitBinaryExpression(GenerateContext<HekateParser.BinaryExpressionContext>(expression));

                    // Verify
                    result.Code.Should().HaveCount(11);
                    result.Code[0].Should().Be((byte)Instruction.Push);
                    result.Code[1].Should().Be(-35);
                    result.Code[2].Should().Be((byte)Instruction.Push);
                    result.Code[3].Should().Be(3);
                    result.Code[4].Should().Be((byte)Instruction.Push);
                    result.Code[5].Should().Be(5);
                    result.Code[6].Should().Be((byte)Instruction.OperatorAdd);
                    result.Code[7].Should().Be((byte)Instruction.Push);
                    result.Code[8].Should().Be(7);
                    result.Code[9].Should().Be((byte)Instruction.OperatorAdd);
                    result.Code[10].Should().Be((byte)Instruction.OperatorAdd);
                }
            }
        }

{'fraction_non_alphanumeric': 0.1107020773073889, 'fraction_numerical': 0.01051801209571391, 'mean_word_length': 1.764171511627907, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1210803', 'n_tokens_mistral': 1919, 'n_tokens_neox': 1814, 'n_words': 296}