input_ut.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #include "input.h"
  2. #include "output.h"
  3. #include <library/cpp/testing/unittest/registar.h>
  4. #include <util/system/file.h>
  5. #include <util/system/yassert.h>
  6. #ifdef _win_
  7. #include <io.h>
  8. #endif
  9. class TMockStdIn {
  10. public:
  11. TMockStdIn()
  12. : StdInCopy_(dup(0))
  13. {
  14. }
  15. ~TMockStdIn() {
  16. close(StdInCopy_);
  17. }
  18. template <typename FuncType>
  19. void ForInput(const TStringBuf text, const FuncType& func) {
  20. TFile tempFile(TFile::Temporary("input_ut"));
  21. tempFile.Write(text.data(), text.size());
  22. tempFile.FlushData();
  23. tempFile.Seek(0, sSet);
  24. TFileHandle tempFh(tempFile.GetHandle());
  25. tempFh.Duplicate2Posix(0);
  26. tempFh.Release();
  27. func();
  28. Cin.ReadAll();
  29. dup2(StdInCopy_, 0);
  30. clearerr(stdin);
  31. }
  32. private:
  33. int StdInCopy_;
  34. };
  35. class TNoInput: public IInputStream {
  36. public:
  37. TNoInput(ui64 size)
  38. : Size_(size)
  39. {
  40. }
  41. protected:
  42. size_t DoRead(void*, size_t len) override {
  43. len = Min(static_cast<ui64>(len), Size_);
  44. Size_ -= len;
  45. return len;
  46. }
  47. private:
  48. ui64 Size_;
  49. };
  50. class TNoOutput: public IOutputStream {
  51. public:
  52. TNoOutput() = default;
  53. protected:
  54. void DoWrite(const void*, size_t) override {
  55. }
  56. };
  57. class TSimpleStringInput: public IInputStream {
  58. public:
  59. TSimpleStringInput(const TString& string)
  60. : String_(string)
  61. {
  62. }
  63. protected:
  64. size_t DoRead(void* buf, size_t len) override {
  65. Y_ASSERT(len != 0);
  66. if (String_.empty()) {
  67. return 0;
  68. }
  69. *static_cast<char*>(buf) = String_[0];
  70. String_.remove(0, 1);
  71. return 1;
  72. }
  73. private:
  74. TString String_;
  75. };
  76. Y_UNIT_TEST_SUITE(TInputTest) {
  77. Y_UNIT_TEST(BigTransfer) {
  78. ui64 size = 1024ull * 1024ull * 1024ull * 5;
  79. TNoInput input(size);
  80. TNoOutput output;
  81. ui64 transferred = TransferData(&input, &output);
  82. UNIT_ASSERT_VALUES_EQUAL(transferred, size);
  83. }
  84. Y_UNIT_TEST(TestReadTo) {
  85. /* This one tests default implementation of ReadTo. */
  86. TSimpleStringInput in("0123456789abc");
  87. TString t;
  88. UNIT_ASSERT_VALUES_EQUAL(in.ReadTo(t, '7'), 8);
  89. UNIT_ASSERT_VALUES_EQUAL(t, "0123456");
  90. UNIT_ASSERT_VALUES_EQUAL(in.ReadTo(t, 'z'), 5);
  91. UNIT_ASSERT_VALUES_EQUAL(t, "89abc");
  92. UNIT_ASSERT_VALUES_EQUAL(in.ReadTo(t, 'z'), 0);
  93. UNIT_ASSERT_VALUES_EQUAL(t, "89abc");
  94. }
  95. Y_UNIT_TEST(TestReadLine) {
  96. TSimpleStringInput in("1\n22\n333");
  97. TString t;
  98. UNIT_ASSERT_VALUES_EQUAL(in.ReadLine(t), 2);
  99. UNIT_ASSERT_VALUES_EQUAL(t, "1");
  100. UNIT_ASSERT_VALUES_EQUAL(in.ReadLine(t), 3);
  101. UNIT_ASSERT_VALUES_EQUAL(t, "22");
  102. UNIT_ASSERT_VALUES_EQUAL(in.ReadLine(t), 3);
  103. UNIT_ASSERT_VALUES_EQUAL(t, "333");
  104. UNIT_ASSERT_VALUES_EQUAL(in.ReadLine(t), 0);
  105. UNIT_ASSERT_VALUES_EQUAL(t, "333");
  106. }
  107. Y_UNIT_TEST(TestStdInReadTo) {
  108. std::pair<std::pair<TStringBuf, char>, TStringBuf> testPairs[] = {
  109. {{"", '\n'}, ""},
  110. {{"\n", '\n'}, ""},
  111. {{"\n\t", '\t'}, "\n"},
  112. {{"\t\n", '\n'}, "\t"},
  113. {{"a\tb\n", '\t'}, "a"}};
  114. TMockStdIn stdIn;
  115. for (const auto& testPair : testPairs) {
  116. const TStringBuf text = testPair.first.first;
  117. const char delim = testPair.first.second;
  118. const TStringBuf expectedValue = testPair.second;
  119. stdIn.ForInput(text,
  120. [=] {
  121. TString value;
  122. Cin.ReadTo(value, delim);
  123. UNIT_ASSERT_VALUES_EQUAL(value, expectedValue);
  124. });
  125. }
  126. }
  127. } // Y_UNIT_TEST_SUITE(TInputTest)