<commit_before>#include <gtest/gtest.h>
#include "lexer/parser_rules.h"

using namespace pegtl;
using namespace fj;

TEST (AST, file_containing_a_class) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object a; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );

    ASSERT_TRUE(status);
    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());

    auto properties = newClass->getProperties();
    ASSERT_EQ(1, properties.size());
    EXPECT_EQ("a", properties.begin()->first);
    EXPECT_EQ("Object", properties.begin()->second);
}

TEST (AST, class_header) {
    const std::string input = "class A extends Object ";

    ClassState classState;

    bool status = parse< fj::class_header, fj::build_class, fj::control>(
        input,
        "input variable",
        classState
    );

    auto classDeclaration = classState.classDeclaration;

    ASSERT_TRUE(status);
    EXPECT_EQ("A", classDeclaration->getName());
    EXPECT_EQ("Object", classDeclaration->getParentName());
}

TEST (AST, single_property_definition) {
    const std::string input = "Object prop1;";

    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::property_def, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    EXPECT_EQ(1, properties.size());
}

TEST (AST, class_body_with_a_single_property) {
    const std::string input = "Object prop1;";
    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::class_body, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    EXPECT_EQ(1, properties.size());
}

TEST (AST, class_body_with_few_properties) {
    const std::string input = "Object prop1 ; Object prop2; ";
    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::class_body, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    ASSERT_EQ(2, properties.size());

    auto firstProperty = properties.begin();
    EXPECT_EQ("prop1", firstProperty->first);
    EXPECT_EQ("Object", firstProperty->second);

    auto lastProperty = properties.rbegin();
    EXPECT_EQ("prop2", lastProperty->first);
    EXPECT_EQ("Object", lastProperty->second);
}

TEST (AST, single_class_with_one_one_property) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );

    ASSERT_TRUE(status);
    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());
}

TEST (AST, class_with_few_properties) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1; Object prop2; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );
    ASSERT_TRUE(status);

    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());

    auto properties = newClass->getProperties();
    ASSERT_EQ(2, properties.size());

    auto firstProperty = properties.begin();
    EXPECT_EQ("prop1", firstProperty->first);
    EXPECT_EQ("Object", firstProperty->second);

    auto lastProperty = properties.rbegin();
    EXPECT_EQ("prop2", lastProperty->first);
    EXPECT_EQ("Object", lastProperty->second);
}

TEST (AST, class_inheritance) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1;}"
            "\nclass B extends A { Object prop2;}";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );
    ASSERT_TRUE(status);

    auto classes = context.getClasses();
    ASSERT_EQ(2, classes.size());

    auto newClass = classes.back();

    EXPECT_EQ("B", newClass->getName());
    EXPECT_EQ("A", newClass->getParentName());
}

TEST (AST, single_method_argument) {
    const std::string input = "Object prop1";
    MethodState methodState;

    bool status = parse< fj::method_arg, fj::build_method, fj::control >(
        input,
        "input variable",
        methodState
    );

    ASSERT_TRUE(status);

    auto methodDeclaration = methodState.methodDeclaration;
    Arguments args = methodDeclaration->getArgs();
    ASSERT_EQ(1, args.size());

    EXPECT_EQ("prop1", args.rbegin()->first);
    EXPECT_EQ("Object", args.rbegin()->second);
}

TEST (AST, a_list_of_method_arguments) {
    const std::string input = "Object a, Object b";
    MethodState methodState;

    bool status = parse< fj::method_arguments, fj::build_method, fj::control >(
        input,
        "input variable",
        methodState
    );

    ASSERT_TRUE(status);

    auto methodDeclaration = methodState.methodDeclaration;
    Arguments args = methodDeclaration->getArgs();
    ASSERT_EQ(2, args.size());

    EXPECT_EQ("b", args.rbegin()->first);
    EXPECT_EQ("Object", args.rbegin()->second);

    EXPECT_EQ("a", args.rend()->first);
    EXPECT_EQ("Object", args.rend()->second);
}

TEST (AST, constructor_header_with_no_arguments) {
    const std::string input = "A()";
    ConstructorState constructorState;

    bool status = parse< fj::constructor_head, fj::build_constructor >(
        input,
        "input variable",
        constructorState
    );

    ASSERT_TRUE(status);

    auto constructorBody = constructorState.constructorBody;
    EXPECT_EQ(0, constructorBody->getArgs().size());
    EXPECT_EQ("A", constructorBody->getName());
}

TEST (AST, constructor_header_with_single_argument) {
    const std::string input = "A( Object fstArg )";
    ConstructorState constructorState;
<commit_msg>Fix test on mac<commit_after>#include <gtest/gtest.h>
#include "lexer/parser_rules.h"

using namespace pegtl;
using namespace fj;

TEST (AST, file_containing_a_class) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object a; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );

    ASSERT_TRUE(status);
    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());

    auto properties = newClass->getProperties();
    ASSERT_EQ(1, properties.size());
    EXPECT_EQ("a", properties.begin()->first);
    EXPECT_EQ("Object", properties.begin()->second);
}

TEST (AST, class_header) {
    const std::string input = "class A extends Object ";

    ClassState classState;

    bool status = parse< fj::class_header, fj::build_class, fj::control>(
        input,
        "input variable",
        classState
    );

    auto classDeclaration = classState.classDeclaration;

    ASSERT_TRUE(status);
    EXPECT_EQ("A", classDeclaration->getName());
    EXPECT_EQ("Object", classDeclaration->getParentName());
}

TEST (AST, single_property_definition) {
    const std::string input = "Object prop1;";

    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::property_def, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    EXPECT_EQ(1, properties.size());
}

TEST (AST, class_body_with_a_single_property) {
    const std::string input = "Object prop1;";
    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::class_body, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    EXPECT_EQ(1, properties.size());
}

TEST (AST, class_body_with_few_properties) {
    const std::string input = "Object prop1 ; Object prop2; ";
    ClassState classState;
    classState.classDeclaration->setName("A");
    classState.classDeclaration->setParentName("Object");

    bool status = parse< fj::class_body, fj::build_class, fj::control >(
        input,
        "input variable",
        classState
    );

    ASSERT_TRUE(status);

    auto classA = classState.classDeclaration;
    auto properties = classA->getProperties();
    ASSERT_EQ(2, properties.size());

    auto firstProperty = properties.begin();
    EXPECT_EQ("prop1", firstProperty->first);
    EXPECT_EQ("Object", firstProperty->second);

    auto lastProperty = properties.rbegin();
    EXPECT_EQ("prop2", lastProperty->first);
    EXPECT_EQ("Object", lastProperty->second);
}

TEST (AST, single_class_with_one_one_property) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );

    ASSERT_TRUE(status);
    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());
}

TEST (AST, class_with_few_properties) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1; Object prop2; }";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );
    ASSERT_TRUE(status);

    auto classes = context.getClasses();
    ASSERT_EQ(1, classes.size());

    auto newClass = classes.front();
    EXPECT_EQ("A", newClass->getName());
    EXPECT_EQ("Object", newClass->getParentName());

    auto properties = newClass->getProperties();
    ASSERT_EQ(2, properties.size());

    auto firstProperty = properties.begin();
    EXPECT_EQ("prop1", firstProperty->first);
    EXPECT_EQ("Object", firstProperty->second);

    auto lastProperty = properties.rbegin();
    EXPECT_EQ("prop2", lastProperty->first);
    EXPECT_EQ("Object", lastProperty->second);
}

TEST (AST, class_inheritance) {
    ParsedContext context;
    const std::string input = "class A extends Object { Object prop1;}"
            "\nclass B extends A { Object prop2;}";
    bool status = parse< fj::grammar, nothing, fj::control >(
        input,
        "input variable",
        context
    );
    ASSERT_TRUE(status);

    auto classes = context.getClasses();
    ASSERT_EQ(2, classes.size());

    auto newClass = classes.back();

    EXPECT_EQ("B", newClass->getName());
    EXPECT_EQ("A", newClass->getParentName());
}

TEST (AST, single_method_argument) {
    const std::string input = "Object prop1";
    MethodState methodState;

    bool status = parse< fj::method_arg, fj::build_method, fj::control >(
        input,
        "input variable",
        methodState
    );

    ASSERT_TRUE(status);

    auto methodDeclaration = methodState.methodDeclaration;
    Arguments args = methodDeclaration->getArgs();
    ASSERT_EQ(1, args.size());

    EXPECT_EQ("prop1", args.rbegin()->first);
    EXPECT_EQ("Object", args.rbegin()->second);
}

TEST (AST, a_list_of_method_arguments) {
    const std::string input = "Object a, Object b";
    MethodState methodState;

    bool status = parse< fj::method_arguments, fj::build_method, fj::control >(
        input,
        "input variable",
        methodState
    );

    ASSERT_TRUE(status);

    auto methodDeclaration = methodState.methodDeclaration;
    Arguments args = methodDeclaration->getArgs();
    ASSERT_EQ(2, args.size());

    EXPECT_EQ("Object", args["b"]);
    EXPECT_EQ("Object", args["a"]);
}

TEST (AST, constructor_header_with_no_arguments) {
    const std::string input = "A()";
    ConstructorState constructorState;

    bool status = parse< fj::constructor_head, fj::build_constructor >(
        input,
        "input variable",
        constructorState
    );

    ASSERT_TRUE(status);

    auto constructorBody = constructorState.constructorBody;
    EXPECT_EQ(0, constructorBody->getArgs().size());
    EXPECT_EQ("A", constructorBody->getName());
}

TEST (AST, constructor_header_with_single_argument) {
    const std::string input = "A( Object fstArg )";
    ConstructorState constructorState;

{'fraction_non_alphanumeric': 0.1351850483859053, 'fraction_numerical': 0.003989067001551304, 'mean_word_length': 3.600067957866123, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 105, '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': '6683826', 'n_tokens_mistral': 4023, 'n_tokens_neox': 3987, 'n_words': 883}