diagnostic_test.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // Copyright (c) 2015-2016 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <algorithm>
  15. #include <sstream>
  16. #include <utility>
  17. #include "gmock/gmock.h"
  18. #include "test/unit_spirv.h"
  19. namespace spvtools {
  20. namespace {
  21. using ::testing::Eq;
  22. // Returns a newly created diagnostic value.
  23. spv_diagnostic MakeValidDiagnostic() {
  24. spv_position_t position = {};
  25. spv_diagnostic diagnostic = spvDiagnosticCreate(&position, "");
  26. EXPECT_NE(nullptr, diagnostic);
  27. return diagnostic;
  28. }
  29. TEST(Diagnostic, DestroyNull) { spvDiagnosticDestroy(nullptr); }
  30. TEST(Diagnostic, DestroyValidDiagnostic) {
  31. spv_diagnostic diagnostic = MakeValidDiagnostic();
  32. spvDiagnosticDestroy(diagnostic);
  33. // We aren't allowed to use the diagnostic pointer anymore.
  34. // So we can't test its behaviour.
  35. }
  36. TEST(Diagnostic, DestroyValidDiagnosticAfterReassignment) {
  37. spv_diagnostic diagnostic = MakeValidDiagnostic();
  38. spv_diagnostic second_diagnostic = MakeValidDiagnostic();
  39. EXPECT_TRUE(diagnostic != second_diagnostic);
  40. spvDiagnosticDestroy(diagnostic);
  41. diagnostic = second_diagnostic;
  42. spvDiagnosticDestroy(diagnostic);
  43. }
  44. TEST(Diagnostic, PrintDefault) {
  45. char message[] = "Test Diagnostic!";
  46. spv_diagnostic_t diagnostic = {{2, 3, 5}, message};
  47. // TODO: Redirect stderr
  48. ASSERT_EQ(SPV_SUCCESS, spvDiagnosticPrint(&diagnostic));
  49. // TODO: Validate the output of spvDiagnosticPrint()
  50. // TODO: Remove the redirection of stderr
  51. }
  52. TEST(Diagnostic, PrintInvalidDiagnostic) {
  53. ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC, spvDiagnosticPrint(nullptr));
  54. }
  55. // TODO(dneto): We should be able to redirect the diagnostic printing.
  56. // Once we do that, we can test diagnostic corner cases.
  57. TEST(DiagnosticStream, ConversionToResultType) {
  58. // Check after the DiagnosticStream object is destroyed.
  59. spv_result_t value;
  60. { value = DiagnosticStream({}, nullptr, "", SPV_ERROR_INVALID_TEXT); }
  61. EXPECT_EQ(SPV_ERROR_INVALID_TEXT, value);
  62. // Check implicit conversion via plain assignment.
  63. value = DiagnosticStream({}, nullptr, "", SPV_SUCCESS);
  64. EXPECT_EQ(SPV_SUCCESS, value);
  65. // Check conversion via constructor.
  66. EXPECT_EQ(SPV_FAILED_MATCH,
  67. spv_result_t(DiagnosticStream({}, nullptr, "", SPV_FAILED_MATCH)));
  68. }
  69. TEST(
  70. DiagnosticStream,
  71. MoveConstructorPreservesPreviousMessagesAndPreventsOutputFromExpiringValue) {
  72. std::ostringstream messages;
  73. int message_count = 0;
  74. auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
  75. const spv_position_t&,
  76. const char* msg) {
  77. message_count++;
  78. messages << msg;
  79. };
  80. // Enclose the DiagnosticStream variables in a scope to force destruction.
  81. {
  82. DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
  83. ds0 << "First";
  84. DiagnosticStream ds1(std::move(ds0));
  85. ds1 << "Second";
  86. }
  87. EXPECT_THAT(message_count, Eq(1));
  88. EXPECT_THAT(messages.str(), Eq("FirstSecond"));
  89. }
  90. TEST(DiagnosticStream, MoveConstructorCanBeDirectlyShiftedTo) {
  91. std::ostringstream messages;
  92. int message_count = 0;
  93. auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
  94. const spv_position_t&,
  95. const char* msg) {
  96. message_count++;
  97. messages << msg;
  98. };
  99. // Enclose the DiagnosticStream variables in a scope to force destruction.
  100. {
  101. DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
  102. ds0 << "First";
  103. std::move(ds0) << "Second";
  104. }
  105. EXPECT_THAT(message_count, Eq(1));
  106. EXPECT_THAT(messages.str(), Eq("FirstSecond"));
  107. }
  108. TEST(DiagnosticStream, DiagnosticFromLambdaReturnCanStillBeUsed) {
  109. std::ostringstream messages;
  110. int message_count = 0;
  111. auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
  112. const spv_position_t&,
  113. const char* msg) {
  114. message_count++;
  115. messages << msg;
  116. };
  117. {
  118. auto emitter = [&consumer]() -> DiagnosticStream {
  119. DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
  120. ds0 << "First";
  121. return ds0;
  122. };
  123. emitter() << "Second";
  124. }
  125. EXPECT_THAT(message_count, Eq(1));
  126. EXPECT_THAT(messages.str(), Eq("FirstSecond"));
  127. }
  128. } // namespace
  129. } // namespace spvtools