-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.test.cpp
132 lines (103 loc) · 4.43 KB
/
token.test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
// Using Catch2 unit testing library
// Let Catch2 define a main function
#define CATCH_CONFIG_MAIN
#include "../include/catch.hpp"
#include "token.hpp"
TEST_CASE("Test Token Equivalence Semantics") {
auto tok1 = Token{TokenType::IDENT, "five"};
auto tok2 = Token{TokenType::IDENT, "ten"};
auto tok3 = Token{TokenType::IDENT, "five"};
auto tok4 = Token{TokenType::STRING, "five"};
auto tok5 = Token{TokenType::STRING, "five"};
REQUIRE(tok1 != tok2);
REQUIRE(tok1 == tok3);
REQUIRE(tok1 != tok4);
REQUIRE(tok1 != tok5);
REQUIRE(tok2 != tok3);
REQUIRE(tok2 != tok4);
REQUIRE(tok2 != tok5);
REQUIRE(tok3 != tok4);
REQUIRE(tok3 != tok5);
REQUIRE(tok4 == tok5);
tok2.literal = "five";
tok4.type = TokenType::IDENT;
tok5.type = TokenType::IDENT;
REQUIRE(tok1 == tok2);
REQUIRE(tok1 == tok3);
REQUIRE(tok1 == tok4);
REQUIRE(tok1 == tok5);
}
TEST_CASE("Test Token Copy Construction") {
auto tok1 = Token{TokenType::IDENT, "five"};
// Get object memory locations before copy
auto address_tok1 = std::addressof(tok1);
auto address_tok1_type = std::addressof(tok1.type);
auto address_tok1_literal = std::addressof(tok1.literal);
// Copy token
Token tok2{tok1};
// Assert that tok1 and tok2 are equivalent after copy
REQUIRE(tok1 == tok2);
// Assert that tok1 and tok2 are are independent after copy
REQUIRE(std::addressof(tok1) != std::addressof(tok2));
REQUIRE(std::addressof(tok1.type) != std::addressof(tok2.type));
REQUIRE(std::addressof(tok1.literal) != std::addressof(tok2.literal));
// Assert that both token and member objects are unchanged after copy
REQUIRE(std::addressof(tok1) == address_tok1);
REQUIRE(std::addressof(tok1.type) == address_tok1_type);
REQUIRE(std::addressof(tok1.literal) == address_tok1_literal);
}
TEST_CASE("Test Token Copy Assignment") {
auto tok1 = Token{TokenType::IDENT, "five"};
auto tok2 = Token{TokenType::LET, "let"};
// Get object memory locations before copy
auto address_tok1 = std::addressof(tok1);
auto address_tok1_type = std::addressof(tok1.type);
auto address_tok1_literal = std::addressof(tok1.literal);
auto address_tok2 = std::addressof(tok2);
auto address_tok2_type = std::addressof(tok2.type);
auto address_tok2_literal = std::addressof(tok2.literal);
// Assert that tok1 and tok2 are not equivalent before copy
REQUIRE(tok1 != tok2);
// Copy token
tok2 = tok1;
// Assert that tok1 and tok2 are equivalent after copy
REQUIRE(tok1 == tok2);
// Assert that tok1 and tok2 are are independent after copy
REQUIRE(std::addressof(tok1) != std::addressof(tok2));
REQUIRE(std::addressof(tok1.type) != std::addressof(tok2.type));
REQUIRE(std::addressof(tok1.literal) != std::addressof(tok2.literal));
// Assert that both token and member objects are unchanged after copy
REQUIRE(std::addressof(tok1) == address_tok1);
REQUIRE(std::addressof(tok1.type) == address_tok1_type);
REQUIRE(std::addressof(tok1.literal) == address_tok1_literal);
REQUIRE(std::addressof(tok2) == address_tok2);
REQUIRE(std::addressof(tok2.type) == address_tok2_type);
REQUIRE(std::addressof(tok2.literal) == address_tok2_literal);
}
TEST_CASE("Test Token Move Construction") {
// No checking of member object addresses, as the enum and string members behave as copy on move
auto tok1 = Token{TokenType::IDENT, "five"};
// Get tok1 values before move
auto tok1_type = TokenType{tok1.type};
auto tok1_literal = std::string{tok1.literal};
// Move token
Token tok2{std::move(tok1)};
// Assert that tok2 members are equivalent to previous values of tok1 after move
REQUIRE(tok2.type == tok1_type);
REQUIRE(tok2.literal == tok1_literal);
}
TEST_CASE("Test Token Move Assignment") {
// No checking of member object addresses, as the enum and string members behave as copy on move
auto tok1 = Token{TokenType::IDENT, "five"};
auto tok2 = Token{TokenType::LET, "let"};
// Get tok1 values before move
auto tok1_type = TokenType{tok1.type};
auto tok1_literal = std::string{tok1.literal};
// Assert that tok1 and tok2 are not equivalent before copy
REQUIRE(tok1 != tok2);
// Move token
tok2 = std::move(tok1);
// Assert that tok2 members are equivalent to previous values of tok1 after move
REQUIRE(tok2.type == tok1_type);
REQUIRE(tok2.literal == tok1_literal);
}