Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/xeus-cpp/xholder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
#include <nlohmann/json.hpp>

#include "xpreamble.hpp"
#include "xeus_cpp_config.hpp"

namespace nl = nlohmann;

namespace xcpp
{
class xholder_preamble
class XEUS_CPP_API xholder_preamble
{
public:

Expand Down
240 changes: 235 additions & 5 deletions test/test_interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,25 @@

#include "doctest/doctest.h"
#include "xeus-cpp/xinterpreter.hpp"
#include "xeus-cpp/xholder.hpp"
#include "xeus-cpp/xmanager.hpp"
#include "xeus-cpp/xutils.hpp"

TEST_SUITE("execute_request")
{
TEST_CASE("fetch_documentation")
{

xcpp::interpreter interpreter(0, nullptr);

std::string code = "?std::vector";
std::string inspect_result = "https://en.cppreference.com/w/cpp/container/vector";
nl::json user_expressions = nl::json::object();

nl::json result = interpreter.execute_request(
code,
false,
false,
user_expressions,
code,
false,
false,
user_expressions,
false
);

Expand All @@ -48,3 +49,232 @@ TEST_SUITE("extract_filename")
REQUIRE(argc == 2);
}
}

TEST_SUITE("should_print_version")
{
// This test case checks if the function `should_print_version` correctly identifies
// when the "--version" argument is passed. It sets up a scenario where "--version"
// is one of the command line arguments and checks if the function returns true.
TEST_CASE("should_print_version_with_version_arg")
{
char arg1[] = "program_name";
char arg2[] = "--version";
char* argv[] = {arg1, arg2};
int argc = 2;

bool result = xcpp::should_print_version(argc, argv);

REQUIRE(result == true);
}

// This test case checks if the function `should_print_version` correctly identifies
// when the "--version" argument is not passed. It sets up a scenario where "--version"
// is not one of the command line arguments and checks if the function returns false.
TEST_CASE("should_print_version_without_version_arg")
{
char arg1[] = "program_name";
char arg2[] = "-f";
char arg3[] = "filename";
char* argv[] = {arg1, arg2, arg3};
int argc = 3;

bool result = xcpp::should_print_version(argc, argv);

REQUIRE(result == false);
}
}

TEST_SUITE("build_interpreter")
{
// This test case checks if the function `build_interpreter` returns a non-null pointer
// when valid arguments are passed. It sets up a scenario with valid command line arguments
// and checks if the function returns a non-null pointer.
TEST_CASE("build_interpreter_pointer_not_null")
{
char arg1[] = "program_name";
char arg2[] = "-option1";
char* argv[] = {arg1, arg2};
int argc = 2;

interpreter_ptr interp_ptr = xcpp::build_interpreter(argc, argv);

REQUIRE(interp_ptr != nullptr);
}
}

TEST_SUITE("is_match_magics_manager")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@brauliorivas if I understand correctly you can improve this test to check xmagics_manager::apply with line magic instead. it would std::regex_search %python same as is_match but also check if the magic can be successfully applied(and possibly record any breaking of the magic commands)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright! I'll change it

Copy link
Contributor Author

@brauliorivas brauliorivas Mar 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @maximusron I'm working on this test case as you said but I'm having trouble with the apply function. If you have time, some help would be handy!

{
// This test case checks if the function `is_match` correctly identifies strings that match
// the regex pattern used in `xmagics_manager`. It sets up a scenario where strings that should
// match the pattern are passed and checks if the function returns true.
TEST_CASE("is_match_true")
{
xcpp::xmagics_manager manager;

bool result1 = manager.is_match("%%magic");
bool result2 = manager.is_match("%magic");

REQUIRE(result1 == true);
REQUIRE(result2 == true);
}

// This test case checks if the function `is_match` correctly identifies strings that do not match
// the regex pattern used in `xmagics_manager`. It sets up a scenario where strings that should not
// match the pattern are passed and checks if the function returns false.
TEST_CASE("is_match_false")
{
xcpp::xmagics_manager manager;

bool result1 = manager.is_match("not a magic");
bool result2 = manager.is_match("%%");
bool result3 = manager.is_match("%");

REQUIRE(result1 == false);
REQUIRE(result2 == false);
REQUIRE(result3 == false);
}
}

TEST_SUITE("clone_magics_manager")
{
// This test case checks if the function `clone_magics_manager` returns a non-null pointer
// when called. It doesn't require any specific setup as it's testing the default behavior
// of the function, and checks if the function returns a non-null pointer.
TEST_CASE("clone_magics_manager_not_null")
{
xcpp::xmagics_manager manager;

xcpp::xpreamble* clone = manager.clone();

REQUIRE(clone != nullptr);
}

// This test case checks if the function `clone_magics_manager` returns a cloned object
// of the same type as the original. It calls the function and checks if the type of the
// returned object matches the type of the original `magics_manager`.
TEST_CASE("clone_magics_manager_same_type")
{
xcpp::xmagics_manager manager;

xcpp::xpreamble* clone = manager.clone();

REQUIRE(dynamic_cast<xcpp::xmagics_manager*>(clone) != nullptr);

delete clone;
}
}

TEST_SUITE("xpreamble_manager_operator")
{
// This test case checks if the `xpreamble_manager` correctly registers and accesses
// a `xpreamble` object. It sets up a scenario where a `xpreamble` object is registered
// with a name and checks if the object can be accessed using the same name.
TEST_CASE("register_and_access")
{
std::string name = "test";
xcpp::xpreamble_manager manager;
xcpp::xmagics_manager* magics = new xcpp::xmagics_manager();
manager.register_preamble(name, magics);

xcpp::xholder_preamble& result = manager.operator[](name);
Copy link
Contributor

@vgvassilev vgvassilev Mar 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably annotate with XEUS_CPP_API the xholder_preamble class to fix the Windows failure...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, I've added this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @vgvassilev, thank you so much for the help, it worked!


REQUIRE(&(result.get_cast<xcpp::xmagics_manager>()) == magics);
}
}

TEST_SUITE("xbuffer")
{
// This test case checks if the `xoutput_buffer` correctly calls the callback function
// when the buffer is flushed. It sets up a scenario where a `xoutput_buffer` object is
// created with a callback function, and checks if the callback function is called when
// the buffer is flushed.
TEST_CASE("xoutput_buffer_calls_callback_on_sync")
{
std::string callback_output;
auto callback = [&callback_output](const std::string& value)
{
callback_output = value;
};
xcpp::xoutput_buffer buffer(callback);
std::ostream stream(&buffer);

stream << "Hello, world!";
stream.flush();

REQUIRE(callback_output == "Hello, world!");
}

// This test case checks if the `xinput_buffer` correctly calls the callback function
// when the buffer is flushed. It sets up a scenario where a `xinput_buffer` object is
// created with a callback function, and checks if the callback function is called when
// the buffer is flushed.
TEST_CASE("xinput_buffer_calls_callback_on_underflow")
{
std::string callback_input;
auto callback = [&callback_input](std::string& value)
{
value = callback_input;
};
xcpp::xinput_buffer buffer(callback);
std::istream stream(&buffer);

callback_input = "Hello, world!";
std::string output;
std::getline(stream, output);

REQUIRE(output == "Hello, world!");
}

// This test case checks if the `xoutput_buffer` correctly handles an empty output.
// It sets up a scenario where the `xoutput_buffer` is given an empty output, then checks
// if the buffer correctly identifies and handles this situation without errors or exceptions.
TEST_CASE("xoutput_buffer_handles_empty_output")
{
std::string callback_output;
auto callback = [&callback_output](const std::string& value)
{
callback_output = value;
};

xcpp::xoutput_buffer buffer(callback);
std::ostream stream(&buffer);

stream << "";
stream.flush();

REQUIRE(callback_output == "");
}

// This test case checks if the `xinput_buffer` correctly handles an empty input.
// It sets up a scenario where the `xinput_buffer` is given an empty input, then checks
// if the buffer correctly identifies and handles this situation without errors or exceptions.
TEST_CASE("xinput_buffer_handles_empty_input")
{
std::string callback_input = "";
auto callback = [&callback_input](std::string& value)
{
value = callback_input;
};

xcpp::xinput_buffer buffer(callback);
std::istream stream(&buffer);

std::string output;
std::getline(stream, output);

REQUIRE(output == "");
}

// This test case checks if the `xnull` correctly discards the output.
// It sets up a scenario where the `xnull` is given some output, then checks
// if the output is correctly discarded and not stored or returned.
TEST_CASE("xnull_discards_output")
{
xcpp::xnull null_buf;
std::ostream null_stream(&null_buf);

null_stream << "Hello, world!";

REQUIRE(null_stream.good() == true);
}
}