1 // SExp - A S-Expression Parser for C++
2 // Copyright (C) 2015 Ingo Ruhnke <grumbel@gmail.com>
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 #include <gtest/gtest.h>
18
19 #include <sstream>
20 #include <stdint.h>
21
22 #include "sexp/value.hpp"
23 #include "sexp/parser.hpp"
24 #include "sexp/io.hpp"
25
TEST(ValueTest,construct_boolean)26 TEST(ValueTest, construct_boolean)
27 {
28 auto sx_bool = sexp::Value::boolean(true);
29 ASSERT_EQ(true, sx_bool.as_bool());
30 }
31
TEST(ValueTest,construct_integer)32 TEST(ValueTest, construct_integer)
33 {
34 auto sx = sexp::Value::integer(12345789);
35 ASSERT_EQ(12345789, sx.as_int());
36 }
37
TEST(ValueTest,construct_real)38 TEST(ValueTest, construct_real)
39 {
40 auto sx = sexp::Value::real(12345.0f);
41 ASSERT_EQ(12345.0f, sx.as_float());
42 }
43
TEST(ValueTest,construct_symbol)44 TEST(ValueTest, construct_symbol)
45 {
46 auto sx = sexp::Value::symbol("Symbol");
47 ASSERT_EQ("Symbol", sx.as_string());
48 }
49
TEST(ValueTest,construct_string)50 TEST(ValueTest, construct_string)
51 {
52 auto sx = sexp::Value::string("HelloWorld");
53 ASSERT_EQ("HelloWorld", sx.as_string());
54 }
55
TEST(ValueTest,construct_array)56 TEST(ValueTest, construct_array)
57 {
58 auto sx = sexp::Value::array(sexp::Value::integer(1),
59 sexp::Value::integer(2),
60 sexp::Value::integer(3),
61 sexp::Value::integer(4));
62 ASSERT_EQ("#(1 2 3 4)", sx.str());
63 sx.append(sexp::Value::integer(5));
64 ASSERT_EQ("#(1 2 3 4 5)", sx.str());
65 }
66
TEST(ValueTest,construct_cons)67 TEST(ValueTest, construct_cons)
68 {
69 auto sx_integer = sexp::Value::integer(12345789);
70 auto sx_cons = sexp::Value::cons(sexp::Value::integer(5), sexp::Value::nil());
71 auto sx_cons2 = sexp::Value::cons(std::move(sx_integer), sexp::Value::nil());
72
73 ASSERT_EQ(12345789, sx_cons2.get_car().as_int());
74 ASSERT_EQ(sexp::Value::nil(), sx_cons2.get_cdr());
75 }
76
TEST(ValueTest,copy)77 TEST(ValueTest, copy)
78 {
79 sexp::Value sx = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
80 sexp::Value sx_copy = sexp::Value(sx);
81 ASSERT_EQ(sx.str(), sx_copy.str());
82 }
83
TEST(ValueTest,equal)84 TEST(ValueTest, equal)
85 {
86 sexp::Value lhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
87 sexp::Value rhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
88 ASSERT_TRUE(lhs == rhs);
89 }
90
TEST(ValueTest,assignment)91 TEST(ValueTest, assignment)
92 {
93 sexp::Value lhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
94 sexp::Value rhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
95 ASSERT_EQ(lhs, rhs);
96 sexp::Value tmp = lhs;
97 lhs = rhs;
98 rhs = tmp;
99 ASSERT_EQ(lhs, rhs);
100 }
101
TEST(ValueTest,type_errors_boolean)102 TEST(ValueTest, type_errors_boolean)
103 {
104 sexp::Value sx = sexp::Value::boolean(true);
105 ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
106 ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
107 ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
108 ASSERT_THROW(sx.get_car(), sexp::TypeError);
109 ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
110
111 ASSERT_THROW(sx.as_int(), sexp::TypeError);
112 ASSERT_THROW(sx.as_float(), sexp::TypeError);
113 ASSERT_THROW(sx.as_string(), sexp::TypeError);
114 }
115
TEST(ValueTest,type_errors_integer)116 TEST(ValueTest, type_errors_integer)
117 {
118 sexp::Value sx = sexp::Value::integer(5);
119 ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
120 ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
121 ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
122 ASSERT_THROW(sx.get_car(), sexp::TypeError);
123 ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
124
125 ASSERT_THROW(sx.as_bool(), sexp::TypeError);
126 ASSERT_THROW(sx.as_string(), sexp::TypeError);
127 }
128
TEST(ValueTest,type_errors_real)129 TEST(ValueTest, type_errors_real)
130 {
131 sexp::Value sx = sexp::Value::real(1.125f);
132 ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
133 ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
134 ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
135 ASSERT_THROW(sx.get_car(), sexp::TypeError);
136 ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
137
138 ASSERT_THROW(sx.as_bool(), sexp::TypeError);
139 ASSERT_THROW(sx.as_string(), sexp::TypeError);
140 }
141
TEST(ValueTest,type_errors_symbol)142 TEST(ValueTest, type_errors_symbol)
143 {
144 sexp::Value sx = sexp::Value::symbol("HelloWorld");
145 ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
146 ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
147 ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
148 ASSERT_THROW(sx.get_car(), sexp::TypeError);
149 ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
150
151 ASSERT_THROW(sx.as_bool(), sexp::TypeError);
152 ASSERT_THROW(sx.as_int(), sexp::TypeError);
153 ASSERT_THROW(sx.as_float(), sexp::TypeError);
154 }
155
TEST(ValueTest,type_errors_string)156 TEST(ValueTest, type_errors_string)
157 {
158 sexp::Value sx = sexp::Value::string("HelloWorld");
159 ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
160 ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
161 ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
162 ASSERT_THROW(sx.get_car(), sexp::TypeError);
163 ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
164
165 ASSERT_THROW(sx.as_bool(), sexp::TypeError);
166 ASSERT_THROW(sx.as_int(), sexp::TypeError);
167 ASSERT_THROW(sx.as_float(), sexp::TypeError);
168 }
169
TEST(ValueTest,type_errors_cons)170 TEST(ValueTest, type_errors_cons)
171 {
172 sexp::Value sx = sexp::Value::cons(sexp::Value::integer(5), sexp::Value::integer(5));
173 ASSERT_THROW(sx.as_bool(), sexp::TypeError);
174 ASSERT_THROW(sx.as_int(), sexp::TypeError);
175 ASSERT_THROW(sx.as_float(), sexp::TypeError);
176 ASSERT_THROW(sx.as_string(), sexp::TypeError);
177 }
178
TEST(ValueTest,object_size)179 TEST(ValueTest, object_size)
180 {
181 #if INTPTR_MAX == INT32_MAX
182 // on 32bit systems
183 # ifdef _MSC_VER
184 ASSERT_EQ(12, sizeof(sexp::Value));
185 # else
186 ASSERT_EQ(8, sizeof(sexp::Value));
187 # endif
188 #elif INTPTR_MAX == INT64_MAX
189 // on 64bit systems
190 ASSERT_EQ(16, sizeof(sexp::Value));
191 #else
192 # error "environment is neither 32 nor 64-bit"
193 #endif
194 }
195
196 /* EOF */
197