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