value_test.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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. #include <gtest/gtest.h>
  17. #include <sstream>
  18. #include <stdint.h>
  19. #include "sexp/value.hpp"
  20. #include "sexp/parser.hpp"
  21. #include "sexp/io.hpp"
  22. TEST(ValueTest, construct_boolean)
  23. {
  24. auto sx_bool = sexp::Value::boolean(true);
  25. ASSERT_EQ(true, sx_bool.as_bool());
  26. }
  27. TEST(ValueTest, construct_integer)
  28. {
  29. auto sx = sexp::Value::integer(12345789);
  30. ASSERT_EQ(12345789, sx.as_int());
  31. }
  32. TEST(ValueTest, construct_real)
  33. {
  34. auto sx = sexp::Value::real(12345.0F);
  35. ASSERT_EQ(12345.0F, sx.as_float());
  36. }
  37. TEST(ValueTest, construct_symbol)
  38. {
  39. auto sx = sexp::Value::symbol("Symbol");
  40. ASSERT_EQ("Symbol", sx.as_string());
  41. }
  42. TEST(ValueTest, construct_string)
  43. {
  44. auto sx = sexp::Value::string("HelloWorld");
  45. ASSERT_EQ("HelloWorld", sx.as_string());
  46. }
  47. TEST(ValueTest, construct_array)
  48. {
  49. auto sx = sexp::Value::array(sexp::Value::integer(1),
  50. sexp::Value::integer(2),
  51. sexp::Value::integer(3),
  52. sexp::Value::integer(4));
  53. ASSERT_EQ("#(1 2 3 4)", sx.str());
  54. sx.append(sexp::Value::integer(5));
  55. ASSERT_EQ("#(1 2 3 4 5)", sx.str());
  56. }
  57. TEST(ValueTest, construct_cons)
  58. {
  59. auto sx_integer = sexp::Value::integer(12345789);
  60. auto sx_cons = sexp::Value::cons(sexp::Value::integer(5), sexp::Value::nil());
  61. auto sx_cons2 = sexp::Value::cons(std::move(sx_integer), sexp::Value::nil());
  62. ASSERT_EQ(12345789, sx_cons2.get_car().as_int());
  63. ASSERT_EQ(sexp::Value::nil(), sx_cons2.get_cdr());
  64. }
  65. TEST(ValueTest, copy)
  66. {
  67. sexp::Value sx = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
  68. sexp::Value sx_copy = sx; // NOLINT
  69. ASSERT_EQ(sx.str(), sx_copy.str());
  70. }
  71. TEST(ValueTest, equal)
  72. {
  73. sexp::Value lhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
  74. sexp::Value rhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
  75. ASSERT_TRUE(lhs == rhs);
  76. }
  77. TEST(ValueTest, assignment)
  78. {
  79. sexp::Value lhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
  80. sexp::Value rhs = sexp::Parser::from_string("(a-symbol #f #t 1 2 3 (4 5 (6 7 8) (9 . 10) \"Hello world\"))");
  81. ASSERT_EQ(lhs, rhs);
  82. sexp::Value tmp = lhs;
  83. lhs = rhs;
  84. rhs = tmp;
  85. ASSERT_EQ(lhs, rhs);
  86. }
  87. TEST(ValueTest, type_errors_boolean)
  88. {
  89. sexp::Value sx = sexp::Value::boolean(true);
  90. ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
  91. ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
  92. ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
  93. ASSERT_THROW(sx.get_car(), sexp::TypeError);
  94. ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
  95. ASSERT_THROW(sx.as_int(), sexp::TypeError);
  96. ASSERT_THROW(sx.as_float(), sexp::TypeError);
  97. ASSERT_THROW(sx.as_string(), sexp::TypeError);
  98. }
  99. TEST(ValueTest, type_errors_integer)
  100. {
  101. sexp::Value sx = sexp::Value::integer(5);
  102. ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
  103. ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
  104. ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
  105. ASSERT_THROW(sx.get_car(), sexp::TypeError);
  106. ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
  107. ASSERT_THROW(sx.as_bool(), sexp::TypeError);
  108. ASSERT_THROW(sx.as_string(), sexp::TypeError);
  109. }
  110. TEST(ValueTest, type_errors_real)
  111. {
  112. sexp::Value sx = sexp::Value::real(1.125F);
  113. ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
  114. ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
  115. ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
  116. ASSERT_THROW(sx.get_car(), sexp::TypeError);
  117. ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
  118. ASSERT_THROW(sx.as_bool(), sexp::TypeError);
  119. ASSERT_THROW(sx.as_string(), sexp::TypeError);
  120. }
  121. TEST(ValueTest, type_errors_symbol)
  122. {
  123. sexp::Value sx = sexp::Value::symbol("HelloWorld");
  124. ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
  125. ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
  126. ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
  127. ASSERT_THROW(sx.get_car(), sexp::TypeError);
  128. ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
  129. ASSERT_THROW(sx.as_bool(), sexp::TypeError);
  130. ASSERT_THROW(sx.as_int(), sexp::TypeError);
  131. ASSERT_THROW(sx.as_float(), sexp::TypeError);
  132. }
  133. TEST(ValueTest, type_errors_string)
  134. {
  135. sexp::Value sx = sexp::Value::string("HelloWorld");
  136. ASSERT_THROW(sx.append(sexp::Value::nil()), sexp::TypeError);
  137. ASSERT_THROW(sx.set_car(sexp::Value::nil()), sexp::TypeError);
  138. ASSERT_THROW(sx.set_cdr(sexp::Value::nil()), sexp::TypeError);
  139. ASSERT_THROW(sx.get_car(), sexp::TypeError);
  140. ASSERT_THROW(sx.get_cdr(), sexp::TypeError);
  141. ASSERT_THROW(sx.as_bool(), sexp::TypeError);
  142. ASSERT_THROW(sx.as_int(), sexp::TypeError);
  143. ASSERT_THROW(sx.as_float(), sexp::TypeError);
  144. }
  145. TEST(ValueTest, type_errors_cons)
  146. {
  147. sexp::Value sx = sexp::Value::cons(sexp::Value::integer(5), sexp::Value::integer(5));
  148. ASSERT_THROW(sx.as_bool(), sexp::TypeError);
  149. ASSERT_THROW(sx.as_int(), sexp::TypeError);
  150. ASSERT_THROW(sx.as_float(), sexp::TypeError);
  151. ASSERT_THROW(sx.as_string(), sexp::TypeError);
  152. }
  153. TEST(ValueTest, object_size)
  154. {
  155. #if INTPTR_MAX == INT32_MAX
  156. // on 32bit systems
  157. # ifdef _MSC_VER
  158. ASSERT_EQ(12, sizeof(sexp::Value));
  159. # else
  160. ASSERT_EQ(8, sizeof(sexp::Value));
  161. # endif
  162. #elif INTPTR_MAX == INT64_MAX
  163. // on 64bit systems
  164. ASSERT_EQ(16, sizeof(sexp::Value));
  165. #else
  166. # error "environment is neither 32 nor 64-bit"
  167. #endif
  168. }
  169. /* EOF */