1 //
2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "PreprocessorTest.h"
8 #include "compiler/preprocessor/Token.h"
9
10 namespace angle
11 {
12
13 class VersionTest : public SimplePreprocessorTest
14 {};
15
TEST_F(VersionTest,Valid)16 TEST_F(VersionTest, Valid)
17 {
18 const char *str = "#version 200\n";
19 const char *expected = "\n";
20
21 using testing::_;
22 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
23 // No error or warning.
24 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
25
26 preprocess(str, expected);
27 }
28
29 // Test for Desktop GL Shaders
TEST_F(VersionTest,GLSpec)30 TEST_F(VersionTest, GLSpec)
31 {
32 const char *str = "#version 330 core\n";
33 const char *expected = "\n";
34
35 using testing::_;
36 EXPECT_CALL(mDirectiveHandler,
37 handleVersion(pp::SourceLocation(0, 1), 330, SH_GL_COMPATIBILITY_SPEC));
38 // No error or warning.
39 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
40
41 preprocess(str, expected, SH_GL_COMPATIBILITY_SPEC);
42 }
43
TEST_F(VersionTest,CommentsIgnored)44 TEST_F(VersionTest, CommentsIgnored)
45 {
46 const char *str =
47 "/*foo*/"
48 "#"
49 "/*foo*/"
50 "version"
51 "/*foo*/"
52 "200"
53 "/*foo*/"
54 "//foo"
55 "\n";
56 const char *expected = "\n";
57
58 using testing::_;
59 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
60 // No error or warning.
61 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
62
63 preprocess(str, expected);
64 }
65
TEST_F(VersionTest,MissingNewline)66 TEST_F(VersionTest, MissingNewline)
67 {
68 const char *str = "#version 200";
69 const char *expected = "";
70
71 using testing::_;
72 // Directive successfully parsed.
73 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 1), 200, SH_GLES2_SPEC));
74 // Error reported about EOF.
75 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_EOF_IN_DIRECTIVE, _, _));
76
77 preprocess(str, expected);
78 }
79
TEST_F(VersionTest,AfterComments)80 TEST_F(VersionTest, AfterComments)
81 {
82 const char *str =
83 "/* block comment acceptable */\n"
84 "// line comment acceptable\n"
85 "#version 200\n";
86 const char *expected = "\n\n\n";
87
88 using testing::_;
89 // Directive successfully parsed.
90 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC));
91 // No error or warning.
92 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
93
94 preprocess(str, expected);
95 }
96
TEST_F(VersionTest,AfterWhitespace)97 TEST_F(VersionTest, AfterWhitespace)
98 {
99 const char *str =
100 "\n"
101 "\n"
102 "#version 200\n";
103 const char *expected = "\n\n\n";
104
105 using testing::_;
106 // Directive successfully parsed.
107 EXPECT_CALL(mDirectiveHandler, handleVersion(pp::SourceLocation(0, 3), 200, SH_GLES2_SPEC));
108 // No error or warning.
109 EXPECT_CALL(mDiagnostics, print(_, _, _)).Times(0);
110
111 preprocess(str, expected);
112 }
113
TEST_F(VersionTest,AfterValidToken)114 TEST_F(VersionTest, AfterValidToken)
115 {
116 const char *str =
117 "foo\n"
118 "#version 200\n";
119
120 using testing::_;
121 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
122 pp::SourceLocation(0, 2), _));
123
124 preprocess(str);
125 }
126
TEST_F(VersionTest,AfterInvalidToken)127 TEST_F(VersionTest, AfterInvalidToken)
128 {
129 const char *str =
130 "$\n"
131 "#version 200\n";
132
133 using testing::_;
134 EXPECT_CALL(mDiagnostics,
135 print(pp::Diagnostics::PP_INVALID_CHARACTER, pp::SourceLocation(0, 1), "$"));
136 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
137 pp::SourceLocation(0, 2), _));
138
139 preprocess(str);
140 }
141
TEST_F(VersionTest,AfterValidDirective)142 TEST_F(VersionTest, AfterValidDirective)
143 {
144 const char *str =
145 "#\n"
146 "#version 200\n";
147
148 using testing::_;
149 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
150 pp::SourceLocation(0, 2), _));
151
152 preprocess(str);
153 }
154
TEST_F(VersionTest,AfterInvalidDirective)155 TEST_F(VersionTest, AfterInvalidDirective)
156 {
157 const char *str =
158 "#foo\n"
159 "#version 200\n";
160
161 using testing::_;
162 EXPECT_CALL(mDiagnostics,
163 print(pp::Diagnostics::PP_DIRECTIVE_INVALID_NAME, pp::SourceLocation(0, 1), "foo"));
164 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
165 pp::SourceLocation(0, 2), _));
166
167 preprocess(str);
168 }
169
TEST_F(VersionTest,AfterExcludedBlock)170 TEST_F(VersionTest, AfterExcludedBlock)
171 {
172 const char *str =
173 "#if 0\n"
174 "foo\n"
175 "#endif\n"
176 "#version 200\n";
177
178 using testing::_;
179 EXPECT_CALL(mDiagnostics, print(pp::Diagnostics::PP_VERSION_NOT_FIRST_STATEMENT,
180 pp::SourceLocation(0, 4), _));
181
182 preprocess(str);
183 }
184
185 struct VersionTestParam
186 {
187 const char *str;
188 pp::Diagnostics::ID id;
189 };
190
191 class InvalidVersionTest : public VersionTest, public testing::WithParamInterface<VersionTestParam>
192 {};
193
TEST_P(InvalidVersionTest,Identified)194 TEST_P(InvalidVersionTest, Identified)
195 {
196 VersionTestParam param = GetParam();
197 const char *expected = "\n";
198
199 using testing::_;
200 // No handleVersion call.
201 EXPECT_CALL(mDirectiveHandler, handleVersion(_, _, _)).Times(0);
202 // Invalid version directive call.
203 EXPECT_CALL(mDiagnostics, print(param.id, pp::SourceLocation(0, 1), _));
204
205 preprocess(param.str, expected);
206 }
207
208 static const VersionTestParam kParams[] = {
209 {"#version\n", pp::Diagnostics::PP_INVALID_VERSION_DIRECTIVE},
210 {"#version foo\n", pp::Diagnostics::PP_INVALID_VERSION_NUMBER},
211 {"#version 100 foo\n", pp::Diagnostics::PP_UNEXPECTED_TOKEN},
212 {"#version 0xffffffff\n", pp::Diagnostics::PP_INTEGER_OVERFLOW}};
213
214 INSTANTIATE_TEST_SUITE_P(All, InvalidVersionTest, testing::ValuesIn(kParams));
215
216 } // namespace angle
217