• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
15 #include <algorithm>
16 #include <sstream>
17 #include <utility>
18 
19 #include "gmock/gmock.h"
20 #include "test/unit_spirv.h"
21 
22 namespace spvtools {
23 namespace {
24 
25 using ::testing::Eq;
26 
27 // Returns a newly created diagnostic value.
MakeValidDiagnostic()28 spv_diagnostic MakeValidDiagnostic() {
29   spv_position_t position = {};
30   spv_diagnostic diagnostic = spvDiagnosticCreate(&position, "");
31   EXPECT_NE(nullptr, diagnostic);
32   return diagnostic;
33 }
34 
TEST(Diagnostic,DestroyNull)35 TEST(Diagnostic, DestroyNull) { spvDiagnosticDestroy(nullptr); }
36 
TEST(Diagnostic,DestroyValidDiagnostic)37 TEST(Diagnostic, DestroyValidDiagnostic) {
38   spv_diagnostic diagnostic = MakeValidDiagnostic();
39   spvDiagnosticDestroy(diagnostic);
40   // We aren't allowed to use the diagnostic pointer anymore.
41   // So we can't test its behaviour.
42 }
43 
TEST(Diagnostic,DestroyValidDiagnosticAfterReassignment)44 TEST(Diagnostic, DestroyValidDiagnosticAfterReassignment) {
45   spv_diagnostic diagnostic = MakeValidDiagnostic();
46   spv_diagnostic second_diagnostic = MakeValidDiagnostic();
47   EXPECT_TRUE(diagnostic != second_diagnostic);
48   spvDiagnosticDestroy(diagnostic);
49   diagnostic = second_diagnostic;
50   spvDiagnosticDestroy(diagnostic);
51 }
52 
TEST(Diagnostic,PrintDefault)53 TEST(Diagnostic, PrintDefault) {
54   char message[] = "Test Diagnostic!";
55   spv_diagnostic_t diagnostic = {{2, 3, 5}, message};
56   // TODO: Redirect stderr
57   ASSERT_EQ(SPV_SUCCESS, spvDiagnosticPrint(&diagnostic));
58   // TODO: Validate the output of spvDiagnosticPrint()
59   // TODO: Remove the redirection of stderr
60 }
61 
TEST(Diagnostic,PrintInvalidDiagnostic)62 TEST(Diagnostic, PrintInvalidDiagnostic) {
63   ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC, spvDiagnosticPrint(nullptr));
64 }
65 
66 // TODO(dneto): We should be able to redirect the diagnostic printing.
67 // Once we do that, we can test diagnostic corner cases.
68 
TEST(DiagnosticStream,ConversionToResultType)69 TEST(DiagnosticStream, ConversionToResultType) {
70   // Check after the DiagnosticStream object is destroyed.
71   spv_result_t value;
72   { value = DiagnosticStream({}, nullptr, "", SPV_ERROR_INVALID_TEXT); }
73   EXPECT_EQ(SPV_ERROR_INVALID_TEXT, value);
74 
75   // Check implicit conversion via plain assignment.
76   value = DiagnosticStream({}, nullptr, "", SPV_SUCCESS);
77   EXPECT_EQ(SPV_SUCCESS, value);
78 
79   // Check conversion via constructor.
80   EXPECT_EQ(SPV_FAILED_MATCH,
81             spv_result_t(DiagnosticStream({}, nullptr, "", SPV_FAILED_MATCH)));
82 }
83 
TEST(DiagnosticStream,MoveConstructorPreservesPreviousMessagesAndPreventsOutputFromExpiringValue)84 TEST(
85     DiagnosticStream,
86     MoveConstructorPreservesPreviousMessagesAndPreventsOutputFromExpiringValue) {
87   std::ostringstream messages;
88   int message_count = 0;
89   auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
90                                               const spv_position_t&,
91                                               const char* msg) {
92     message_count++;
93     messages << msg;
94   };
95 
96   // Enclose the DiagnosticStream variables in a scope to force destruction.
97   {
98     DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
99     ds0 << "First";
100     DiagnosticStream ds1(std::move(ds0));
101     ds1 << "Second";
102   }
103   EXPECT_THAT(message_count, Eq(1));
104   EXPECT_THAT(messages.str(), Eq("FirstSecond"));
105 }
106 
TEST(DiagnosticStream,MoveConstructorCanBeDirectlyShiftedTo)107 TEST(DiagnosticStream, MoveConstructorCanBeDirectlyShiftedTo) {
108   std::ostringstream messages;
109   int message_count = 0;
110   auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
111                                               const spv_position_t&,
112                                               const char* msg) {
113     message_count++;
114     messages << msg;
115   };
116 
117   // Enclose the DiagnosticStream variables in a scope to force destruction.
118   {
119     DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
120     ds0 << "First";
121     std::move(ds0) << "Second";
122   }
123   EXPECT_THAT(message_count, Eq(1));
124   EXPECT_THAT(messages.str(), Eq("FirstSecond"));
125 }
126 
TEST(DiagnosticStream,DiagnosticFromLambdaReturnCanStillBeUsed)127 TEST(DiagnosticStream, DiagnosticFromLambdaReturnCanStillBeUsed) {
128   std::ostringstream messages;
129   int message_count = 0;
130   auto consumer = [&messages, &message_count](spv_message_level_t, const char*,
131                                               const spv_position_t&,
132                                               const char* msg) {
133     message_count++;
134     messages << msg;
135   };
136 
137   {
138     auto emitter = [&consumer]() -> DiagnosticStream {
139       DiagnosticStream ds0({}, consumer, "", SPV_ERROR_INVALID_BINARY);
140       ds0 << "First";
141       return ds0;
142     };
143     emitter() << "Second";
144   }
145   EXPECT_THAT(message_count, Eq(1));
146   EXPECT_THAT(messages.str(), Eq("FirstSecond"));
147 }
148 
149 }  // namespace
150 }  // namespace spvtools
151