Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 

170 rindas
4.7 KiB

  1. #pragma once
  2. #include <string>
  3. #include <gtest/gtest.h>
  4. #include <gmock/gmock.h>
  5. #include "mariadb_mock.h"
  6. ACTION(EscapeString)
  7. {
  8. char* dst = arg0;
  9. const char* src = arg1;
  10. unsigned long len = arg2;
  11. if (len <= 0)
  12. return 0;
  13. *(dst++) = 'X';
  14. for (unsigned long i = 0; i < len; ++i)
  15. *(dst++) = *(src++);
  16. *(dst++) = 'X';
  17. return len + 2;
  18. }
  19. struct result_data
  20. : public mariadb_mock_item
  21. {
  22. using row_type = std::vector<const char *>;
  23. using data_type = std::vector<row_type>;
  24. struct internal_data_t
  25. {
  26. std::vector<char*> data;
  27. std::vector<unsigned long> length;
  28. };
  29. using interal_data_vector = std::vector<internal_data_t>;
  30. bool is_stored;
  31. ssize_t affected_rows;
  32. data_type data;
  33. interal_data_vector internal_data;
  34. template<typename T_data>
  35. result_data(T_data&& p_data, bool p_is_stored, ssize_t p_affected_rows)
  36. : data (std::forward<T_data>(p_data))
  37. , is_stored (p_is_stored)
  38. , affected_rows (p_affected_rows)
  39. {
  40. internal_data.resize(data.size());
  41. for (size_t i = 0; i < data.size(); ++i)
  42. {
  43. auto& intern = internal_data.at(i);
  44. auto& d = data.at(i);
  45. intern.data.resize(d.size());
  46. intern.length.resize(d.size());
  47. for (size_t j = 0; j < d.size(); ++j)
  48. {
  49. auto& str = d.at(j);
  50. intern.data[j] = const_cast<char*>(str);
  51. intern.length[j] = static_cast<unsigned long>(str ? strlen(str) : 0);
  52. }
  53. }
  54. }
  55. };
  56. inline MYSQL_RES* next_result()
  57. {
  58. static size_t value = 0x2000;
  59. return reinterpret_cast<MYSQL_RES*>(value++);
  60. }
  61. inline const result_data::data_type& empty_result_data()
  62. {
  63. static const result_data::data_type value;
  64. return value;
  65. }
  66. template<typename T_data = decltype(empty_result_data())>
  67. inline decltype(auto) result_stored(T_data&& data = empty_result_data(), ssize_t affected_rows = -1)
  68. { return result_data(std::forward<T_data>(data), true, affected_rows); }
  69. template<typename T_data = decltype(empty_result_data())>
  70. inline decltype(auto) result_used(T_data&& data = empty_result_data(), ssize_t affected_rows = -1)
  71. { return result_data(std::forward<T_data>(data), false, affected_rows); }
  72. inline decltype(auto) result_affected_rows(ssize_t affected_rows)
  73. { return result_data(empty_result_data(), true, affected_rows); }
  74. template<typename T_mock, typename T_result>
  75. inline void expect_query(T_mock& mock, const std::string& query, T_result&& result)
  76. {
  77. EXPECT_CALL(
  78. mock,
  79. mysql_real_query(
  80. reinterpret_cast<MYSQL*>(0x1111),
  81. ::testing::StrEq(query),
  82. query.size()))
  83. .InSequence(mock.sequence);
  84. auto& res = mock.store(std::forward<T_result>(result));
  85. auto ptr = next_result();
  86. if (res.is_stored)
  87. {
  88. EXPECT_CALL(
  89. mock,
  90. mysql_store_result(reinterpret_cast<MYSQL*>(0x1111)))
  91. .InSequence(mock.sequence)
  92. .WillOnce(::testing::Return(ptr));
  93. }
  94. else
  95. {
  96. EXPECT_CALL(
  97. mock,
  98. mysql_use_result(reinterpret_cast<MYSQL*>(0x1111)))
  99. .InSequence(mock.sequence)
  100. .WillOnce(::testing::Return(ptr));
  101. }
  102. if (res.affected_rows >= 0)
  103. {
  104. EXPECT_CALL(
  105. mock,
  106. mysql_affected_rows(reinterpret_cast<MYSQL*>(0x1111)))
  107. .InSequence(mock.sequence)
  108. .WillOnce(::testing::Return(static_cast<unsigned long long>(res.affected_rows)));
  109. }
  110. if (!res.data.empty())
  111. {
  112. EXPECT_CALL(
  113. mock,
  114. mysql_num_fields(ptr))
  115. .Times(::testing::AnyNumber())
  116. .WillRepeatedly(::testing::Return(res.data.at(0).size()));
  117. }
  118. for (auto& x : res.internal_data)
  119. {
  120. EXPECT_CALL(
  121. mock,
  122. mysql_fetch_row(ptr))
  123. .InSequence(mock.sequence)
  124. .WillOnce(::testing::Return(x.data.data()));
  125. EXPECT_CALL(
  126. mock,
  127. mysql_fetch_lengths(ptr))
  128. .InSequence(mock.sequence)
  129. .WillOnce(::testing::Return(x.length.data()));
  130. }
  131. if (!res.is_stored)
  132. {
  133. EXPECT_CALL(
  134. mock,
  135. mysql_fetch_row(ptr))
  136. .InSequence(mock.sequence)
  137. .WillOnce(::testing::Return(nullptr));
  138. }
  139. EXPECT_CALL(
  140. mock,
  141. mysql_free_result(ptr))
  142. .InSequence(mock.sequence);
  143. }
  144. template<typename T_mock>
  145. inline void expect_query(T_mock& mock, const std::string& query)
  146. { expect_query(mock, query, result_stored()); }