153 lines
5.8 KiB
C++
153 lines
5.8 KiB
C++
|
|
// Step 468: Operator Overloading + Friend Tests (12 tests)
|
||
|
|
|
||
|
|
#include "ast/CppOperators.h"
|
||
|
|
|
||
|
|
#include <iostream>
|
||
|
|
|
||
|
|
static int passed = 0, failed = 0;
|
||
|
|
#define TEST(name) { std::cout << " " << #name << "... "; }
|
||
|
|
#define PASS() { std::cout << "PASS\n"; ++passed; }
|
||
|
|
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
|
||
|
|
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
|
||
|
|
|
||
|
|
void test_parse_member_operator_less_const() {
|
||
|
|
TEST(parse_member_operator_less_const);
|
||
|
|
OperatorOverload o;
|
||
|
|
bool ok = CppOperators::parseOperatorOverload("bool operator<(const Foo&) const;", o);
|
||
|
|
CHECK(ok, "parse should succeed");
|
||
|
|
CHECK(o.operatorSymbol == "<", "wrong operator symbol");
|
||
|
|
CHECK(o.returnType == "bool", "wrong return type");
|
||
|
|
CHECK(o.isConst, "expected const qualifier");
|
||
|
|
CHECK(!o.isFriend, "member overload should not be friend");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_parse_friend_operator_stream_insertion() {
|
||
|
|
TEST(parse_friend_operator_stream_insertion);
|
||
|
|
OperatorOverload o;
|
||
|
|
bool ok = CppOperators::parseOperatorOverload(
|
||
|
|
"friend ostream& operator<<(ostream&, const Foo&);", o);
|
||
|
|
CHECK(ok, "parse should succeed");
|
||
|
|
CHECK(o.operatorSymbol == "<<", "wrong operator symbol");
|
||
|
|
CHECK(o.isFriend, "expected friend");
|
||
|
|
CHECK(o.parameters.size() == 2, "expected two parameters");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_parse_operator_equals() {
|
||
|
|
TEST(parse_operator_equals);
|
||
|
|
OperatorOverload o;
|
||
|
|
bool ok = CppOperators::parseOperatorOverload(
|
||
|
|
"bool operator==(const Foo& rhs) const;", o);
|
||
|
|
CHECK(ok, "parse should succeed");
|
||
|
|
CHECK(o.operatorSymbol == "==", "wrong operator symbol");
|
||
|
|
CHECK(o.isConst, "expected const");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_parse_operator_plus_non_const() {
|
||
|
|
TEST(parse_operator_plus_non_const);
|
||
|
|
OperatorOverload o;
|
||
|
|
bool ok = CppOperators::parseOperatorOverload(
|
||
|
|
"Foo operator+(const Foo& rhs);", o);
|
||
|
|
CHECK(ok, "parse should succeed");
|
||
|
|
CHECK(o.operatorSymbol == "+", "wrong operator symbol");
|
||
|
|
CHECK(!o.isConst, "unexpected const");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_parse_invalid_declaration_fails() {
|
||
|
|
TEST(parse_invalid_declaration_fails);
|
||
|
|
OperatorOverload o;
|
||
|
|
bool ok = CppOperators::parseOperatorOverload("int notAnOperator(int x);", o);
|
||
|
|
CHECK(!ok, "non-operator declaration should fail");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_operator_json_roundtrip() {
|
||
|
|
TEST(operator_json_roundtrip);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("bool operator<(const Foo&) const;", o);
|
||
|
|
auto j = CppOperators::toJson(o);
|
||
|
|
auto out = CppOperators::fromJson(j);
|
||
|
|
CHECK(out.operatorSymbol == o.operatorSymbol, "operator symbol mismatch");
|
||
|
|
CHECK(out.returnType == o.returnType, "return type mismatch");
|
||
|
|
CHECK(out.isConst == o.isConst, "const flag mismatch");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_generate_cpp_declaration_member() {
|
||
|
|
TEST(generate_cpp_declaration_member);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("bool operator<(const Foo&) const;", o);
|
||
|
|
auto s = CppOperators::generateCppDeclaration(o);
|
||
|
|
CHECK(s == "bool operator<(const Foo&) const;", "wrong generated declaration");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_generate_cpp_declaration_friend() {
|
||
|
|
TEST(generate_cpp_declaration_friend);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("friend ostream& operator<<(ostream&, const Foo&);", o);
|
||
|
|
auto s = CppOperators::generateCppDeclaration(o);
|
||
|
|
CHECK(s.find("friend ostream& operator<<") == 0, "missing friend declaration start");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_project_less_to_java_compare_to() {
|
||
|
|
TEST(project_less_to_java_compare_to);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("bool operator<(const Foo&) const;", o);
|
||
|
|
auto java = CppOperators::projectToJavaMethod(o);
|
||
|
|
CHECK(java.find("compareTo") != std::string::npos, "expected compareTo projection");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_project_less_to_python_dunder_lt() {
|
||
|
|
TEST(project_less_to_python_dunder_lt);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("bool operator<(const Foo&) const;", o);
|
||
|
|
auto py = CppOperators::projectToPythonMethod(o);
|
||
|
|
CHECK(py.find("__lt__") != std::string::npos, "expected __lt__ projection");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_project_equals_to_python_dunder_eq() {
|
||
|
|
TEST(project_equals_to_python_dunder_eq);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("bool operator==(const Foo&) const;", o);
|
||
|
|
auto py = CppOperators::projectToPythonMethod(o);
|
||
|
|
CHECK(py.find("__eq__") != std::string::npos, "expected __eq__ projection");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
void test_project_stream_operator_to_java_display_method() {
|
||
|
|
TEST(project_stream_operator_to_java_display_method);
|
||
|
|
OperatorOverload o;
|
||
|
|
CppOperators::parseOperatorOverload("friend ostream& operator<<(ostream&, const Foo&);", o);
|
||
|
|
auto java = CppOperators::projectToJavaMethod(o);
|
||
|
|
CHECK(java.find("toDisplayString") != std::string::npos, "expected display projection");
|
||
|
|
PASS();
|
||
|
|
}
|
||
|
|
|
||
|
|
int main() {
|
||
|
|
std::cout << "Step 468: Operator Overloading + Friend Tests\n";
|
||
|
|
|
||
|
|
test_parse_member_operator_less_const(); // 1
|
||
|
|
test_parse_friend_operator_stream_insertion(); // 2
|
||
|
|
test_parse_operator_equals(); // 3
|
||
|
|
test_parse_operator_plus_non_const(); // 4
|
||
|
|
test_parse_invalid_declaration_fails(); // 5
|
||
|
|
test_operator_json_roundtrip(); // 6
|
||
|
|
test_generate_cpp_declaration_member(); // 7
|
||
|
|
test_generate_cpp_declaration_friend(); // 8
|
||
|
|
test_project_less_to_java_compare_to(); // 9
|
||
|
|
test_project_less_to_python_dunder_lt(); // 10
|
||
|
|
test_project_equals_to_python_dunder_eq(); // 11
|
||
|
|
test_project_stream_operator_to_java_display_method(); // 12
|
||
|
|
|
||
|
|
std::cout << "\nResults: " << passed << "/" << (passed + failed)
|
||
|
|
<< " passed\n";
|
||
|
|
return failed == 0 ? 0 : 1;
|
||
|
|
}
|