Skip to content

Commit 718abfd

Browse files
committed
feat(tests, vm): adding tests for type checking error messages
1 parent ae6ab6b commit 718abfd

File tree

66 files changed

+350
-39
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+350
-39
lines changed

include/Ark/Compiler/IntermediateRepresentation/Entity.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include <cinttypes>
1616
#include <vector>
17+
#include <string>
1718

1819
#include <Ark/Compiler/IntermediateRepresentation/Word.hpp>
1920
#include <Ark/Compiler/Instructions.hpp>

include/Ark/Exceptions.hpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,10 @@ namespace Ark
3636
std::runtime_error(message)
3737
{}
3838

39-
[[nodiscard]] virtual std::string details() const
39+
[[nodiscard]] virtual std::string details(bool colorize [[maybe_unused]]) const
4040
{
4141
return what();
4242
}
43-
44-
Error& colorize(const bool toggle) noexcept
45-
{
46-
m_colorize = toggle;
47-
return *this;
48-
}
49-
50-
[[nodiscard]] bool shouldColorize() const noexcept
51-
{
52-
return m_colorize;
53-
}
54-
55-
private:
56-
bool m_colorize = true;
5743
};
5844

5945
/**
@@ -85,7 +71,7 @@ namespace Ark
8571
public:
8672
NestedError(const Error& e, const std::string& details) :
8773
Error("NestedError"),
88-
m_details(Error(e).colorize(false).details() + "\n" + details)
74+
m_details(e.details(/* colorize= */ false) + "\n" + details)
8975
{}
9076

9177
NestedError(const std::exception& e, const std::string& details) :

include/Ark/TypeChecker.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <string>
1616
#include <vector>
1717
#include <ostream>
18+
#include <sstream>
1819

1920
#include <Ark/VM/Value.hpp>
2021

@@ -111,10 +112,10 @@ namespace Ark::types
111112
m_passed_args(args)
112113
{}
113114

114-
[[nodiscard]] std::string details() const override
115+
[[nodiscard]] std::string details(const bool colorize) const override
115116
{
116117
std::stringstream stream;
117-
generateError(m_funcname, m_contracts, m_passed_args, stream, shouldColorize());
118+
generateError(m_funcname, m_contracts, m_passed_args, stream, colorize);
118119
return stream.str();
119120
}
120121

src/arkreactor/Compiler/IntermediateRepresentation/IRCompiler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <chrono>
44
#include <utility>
5+
#include <optional>
56
#include <unordered_map>
67
#include <Proxy/Picosha2.hpp>
78
#include <fmt/ostream.h>

src/arkreactor/VM/VM.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ namespace Ark
756756

757757
if (list->valueType() != ValueType::List)
758758
throw types::TypeCheckingError(
759-
"concat",
759+
"concat!",
760760
{ { types::Contract { { types::Typedef("list", ValueType::List) } } } },
761761
{ *list });
762762

@@ -842,7 +842,7 @@ namespace Ark
842842
{ types::Typedef("string", ValueType::String),
843843
types::Typedef("index", ValueType::Number),
844844
types::Typedef("char", ValueType::String) } } } },
845-
{ *list, number });
845+
{ *list, number, new_value });
846846

847847
const std::size_t size = list->valueType() == ValueType::List ? list->list().size() : list->stringRef().size();
848848
long idx = static_cast<long>(number.number());
@@ -876,7 +876,7 @@ namespace Ark
876876
types::Typedef("x", ValueType::Number),
877877
types::Typedef("y", ValueType::Number),
878878
types::Typedef("new_value", ValueType::Any) } } } },
879-
{ *list, x, y });
879+
{ *list, x, y, new_value });
880880

881881
long idx_y = static_cast<long>(x.number());
882882
idx_y = idx_y < 0 ? static_cast<long>(list->list().size()) + idx_y : idx_y;
@@ -899,7 +899,7 @@ namespace Ark
899899
types::Typedef("x", ValueType::Number),
900900
types::Typedef("y", ValueType::Number),
901901
types::Typedef("char", ValueType::String) } } } },
902-
{ *list, x, y });
902+
{ *list, x, y, new_value });
903903

904904
const bool is_list = list->list()[static_cast<std::size_t>(idx_y)].valueType() == ValueType::List;
905905
const std::size_t size =
@@ -1554,7 +1554,7 @@ namespace Ark
15541554
throw NestedError(e, stream.str());
15551555
}
15561556
else
1557-
showBacktraceWithException(Error(e.details()), context);
1557+
showBacktraceWithException(Error(e.details(/* colorize= */ true)), context);
15581558
}
15591559
catch (const std::exception& e)
15601560
{

tests/unittests/Suites/DiagnosticsSuite.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ ut::suite<"Diagnostics"> diagnostics_suite = [] {
2525
}
2626
catch (const Ark::CodeError& e)
2727
{
28-
std::string diag = sanitizeError(e, /* remove_in_file_line= */ true);
28+
std::string diag = sanitizeCodeError(e, /* remove_in_file_line= */ true);
2929
rtrim(diag);
3030
expectOrDiff(data.expected, diag);
3131
}
@@ -50,17 +50,31 @@ ut::suite<"Diagnostics"> diagnostics_suite = [] {
5050
}
5151
catch (const std::exception& e)
5252
{
53-
std::string diag = e.what();
54-
// because of windows
55-
diag.erase(std::ranges::remove(diag, '\r').begin(), diag.end());
56-
// remove the directory prefix so that we are environment agnostic
57-
while (diag.find(ARK_TESTS_ROOT) != std::string::npos)
58-
diag.erase(diag.find(ARK_TESTS_ROOT), std::size(ARK_TESTS_ROOT) - 1);
59-
ltrim(rtrim(diag));
60-
// remove last line, At IP:.., PP:.., SP:..
61-
diag.erase(diag.find_last_of('\n'), diag.size() - 1);
62-
// we most likely have a blank line at the end now
63-
rtrim(diag);
53+
std::string diag = sanitizeRuntimeError(e);
54+
expectOrDiff(data.expected, diag);
55+
}
56+
};
57+
});
58+
59+
iterTestFiles(
60+
"DiagnosticsSuite/typeChecking",
61+
[](TestData&& data) {
62+
Ark::State state({ lib_path });
63+
64+
should("compile without error typeChecking/" + data.stem) = [&] {
65+
expect(mut(state).doFile(data.path, features));
66+
};
67+
68+
should("generate an error at runtime (typeChecking) in " + data.stem) = [&] {
69+
try
70+
{
71+
Ark::VM vm(state);
72+
vm.run(/* fail_with_exception= */ true);
73+
expect(0 == 1); // we shouldn't be here, an error should be generated
74+
}
75+
catch (const std::exception& e)
76+
{
77+
std::string diag = sanitizeRuntimeError(e);
6478
expectOrDiff(data.expected, diag);
6579
}
6680
};

tests/unittests/Suites/ParserSuite.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ ut::suite<"Parser"> parser_suite = [] {
7878
catch (const Ark::CodeError& e)
7979
{
8080
should("output the same error message (" + data.stem + ")") = [&] {
81-
std::string tested = sanitizeError(e);
81+
std::string tested = sanitizeCodeError(e);
8282
ltrim(rtrim(tested));
8383
expectOrDiff(data.expected, tested);
8484
};

tests/unittests/TestsHelper.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ std::string getResourcePath(const std::string& folder)
4444
return (ARK_TESTS_ROOT "tests/unittests/resources/") + folder;
4545
}
4646

47-
std::string sanitizeError(const Ark::CodeError& e, const bool remove_in_file_line)
47+
std::string sanitizeCodeError(const Ark::CodeError& e, const bool remove_in_file_line)
4848
{
4949
std::stringstream stream;
5050
Ark::Diagnostics::generate(e, stream, /* colorize= */ false);
@@ -60,6 +60,27 @@ std::string sanitizeError(const Ark::CodeError& e, const bool remove_in_file_lin
6060
return diag;
6161
}
6262

63+
std::string sanitizeRuntimeError(const std::exception& e)
64+
{
65+
// std::replace(s.begin(), s.end(), '\\', '/');
66+
std::string diag = e.what();
67+
68+
// because of windows
69+
diag.erase(std::ranges::remove(diag, '\r').begin(), diag.end());
70+
std::ranges::replace(diag, '\\', '/');
71+
72+
// remove the directory prefix so that we are environment agnostic
73+
while (diag.find(ARK_TESTS_ROOT) != std::string::npos)
74+
diag.erase(diag.find(ARK_TESTS_ROOT), std::size(ARK_TESTS_ROOT) - 1);
75+
ltrim(rtrim(diag));
76+
// remove last line, At IP:.., PP:.., SP:..
77+
diag.erase(diag.find_last_of('\n'), diag.size() - 1);
78+
// we most likely have a blank line at the end now
79+
rtrim(diag);
80+
81+
return diag;
82+
}
83+
6384
void expectOrDiff(const std::string& expected, const std::string& received)
6485
{
6586
const bool comparison = expected == received;

tests/unittests/TestsHelper.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ inline std::string& rtrim(std::string& s)
7676
return s;
7777
}
7878

79-
std::string sanitizeError(const Ark::CodeError& e, bool remove_in_file_line = false);
79+
std::string sanitizeCodeError(const Ark::CodeError& e, bool remove_in_file_line = false);
80+
81+
std::string sanitizeRuntimeError(const std::exception& e);
8082

8183
void expectOrDiff(const std::string& expected, const std::string& received);
8284

0 commit comments

Comments
 (0)