1# Copyright 2015 The Shaderc Authors. All rights reserved.
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
15import expect
16from glslc_test_framework import inside_glslc_testsuite
17from placeholder import SpecializedString
18from environment import File, Directory
19
20
21@inside_glslc_testsuite('Include')
22class VerifyIncludeOneSibling(expect.StdoutMatch):
23    """Tests #including a sibling file."""
24
25    environment = Directory('.', [
26        File('a.vert', '#version 140\ncontent a\n#include "b"\n'),
27        File('b', 'content b\n')])
28
29    glslc_args = ['-E', 'a.vert']
30
31    expected_stdout = \
32"""#version 140
33#extension GL_GOOGLE_include_directive : enable
34#line 0 "a.vert"
35
36content a
37#line 0 "b"
38 content b
39#line 3 "a.vert"
40
41"""
42
43@inside_glslc_testsuite('Include')
44class VerifyIncludeNotFound(expect.ErrorMessage):
45    """Tests #including a not existing sibling file."""
46
47    environment = Directory('.', [
48        File('a.vert', '#version 140\ncontent a\n#include "b"\n')])
49
50    glslc_args = ['-E', 'a.vert']
51    expected_error = [
52        "a.vert:3: error: '#include' : Cannot find or open include file. for header name: b\n",
53        '1 error generated.\n'
54    ]
55
56@inside_glslc_testsuite('Include')
57class VerifyCompileIncludeOneSibling(expect.ValidObjectFile):
58    """Tests #including a sibling file via full compilation."""
59
60    environment = Directory('.', [
61        File('a.vert', '#version 140\nvoid foo(){}\n#include "b"\n'),
62        File('b', 'void main(){foo();}\n')])
63
64    glslc_args = ['a.vert']
65
66@inside_glslc_testsuite('Include')
67class VerifyIncludeWithoutNewline(expect.ErrorMessageSubstr):
68    """Tests a #include without a newline."""
69
70    environment = Directory('.', [
71        File('a.vert', '#version 140\n#include "b"'),
72        File('b', 'content b\n')])
73
74    glslc_args = ['-E', 'a.vert']
75
76    expected_error_substr = 'expected newline after header name: b'
77
78
79@inside_glslc_testsuite('Include')
80class VerifyCompileIncludeWithoutNewline(expect.ValidObjectFile):
81    """Tests a #include without a newline via full compilation."""
82
83    environment = Directory('.', [
84        File('a.vert',
85             """#version 140
86             void main
87             #include "b"
88             """),
89        File('b',
90             """#define PAR ()
91             PAR{}
92             """)])
93
94    glslc_args = ['a.vert']
95
96@inside_glslc_testsuite('Include')
97class VerifyIncludeTwoSiblings(expect.StdoutMatch):
98    """Tests #including two sibling files."""
99
100    environment = Directory('.', [
101        File('b.vert', '#version 140\n#include "a"\ncontent b\n#include "c"\n'),
102        File('a', 'content a\n'),
103        File('c', 'content c\n')])
104
105    glslc_args = ['-E', 'b.vert']
106
107    expected_stdout = \
108"""#version 140
109#extension GL_GOOGLE_include_directive : enable
110#line 0 "b.vert"
111
112#line 0 "a"
113content a
114#line 2 "b.vert"
115 content b
116#line 0 "c"
117 content c
118#line 4 "b.vert"
119
120"""
121
122@inside_glslc_testsuite('Include')
123class VerifyCompileIncludeTwoSiblings(expect.ValidObjectFile):
124    """Tests #including two sibling files via full compilation."""
125
126    environment = Directory('.', [
127        File('b.vert',
128             """#version 140
129             #include "a"
130             void bfun(){afun();}
131             #include "c"
132             """),
133        File('a',
134             """void afun(){}
135             #define BODY {}
136             """),
137        File('c', 'void main() BODY\n')])
138
139    glslc_args = ['b.vert']
140
141@inside_glslc_testsuite('Include')
142class VerifyNestedIncludeAmongSiblings(expect.StdoutMatch):
143    """Tests #include inside #included sibling files."""
144
145    environment = Directory('.', [
146        File('a.vert', '#version 140\n#include "b"\ncontent a\n'),
147        File('b', 'content b\n#include "c"\n'),
148        File('c', 'content c\n')])
149
150    glslc_args = ['-E', 'a.vert']
151
152    expected_stdout = \
153"""#version 140
154#extension GL_GOOGLE_include_directive : enable
155#line 0 "a.vert"
156
157#line 0 "b"
158content b
159#line 0 "c"
160 content c
161#line 2 "b"
162#line 2 "a.vert"
163 content a
164"""
165
166@inside_glslc_testsuite('Include')
167class VerifyCompileNestedIncludeAmongSiblings(expect.ValidObjectFile):
168    """Tests #include inside #included sibling files via full compilation."""
169
170    environment = Directory('.', [
171        File('a.vert',
172             """#version 140
173             #define BODY {}
174             #include "b"
175             void main(){cfun();}
176             """),
177        File('b',
178             """void bfun() BODY
179             #include "c"
180             """),
181        File('c',
182             """#define BF bfun()
183             void cfun(){BF;}
184             """)])
185
186    glslc_args = ['a.vert']
187
188@inside_glslc_testsuite('Include')
189class VerifyIncludeSubdir(expect.StdoutMatch):
190    """Tests #including a file from a subdirectory."""
191
192    environment = Directory('.', [
193        File('a.vert', '#version 140\ncontent a1\n#include "subdir/a"\ncontent a2\n'),
194        Directory('subdir', [File('a', 'content suba\n')])])
195
196    glslc_args = ['-E', 'a.vert']
197
198    expected_stdout = \
199"""#version 140
200#extension GL_GOOGLE_include_directive : enable
201#line 0 "a.vert"
202
203content a1
204#line 0 "subdir/a"
205 content suba
206#line 3 "a.vert"
207 content a2
208"""
209
210@inside_glslc_testsuite('Include')
211class VerifyCompileIncludeSubdir(expect.ValidObjectFile):
212    """Tests #including a file from a subdirectory via full compilation."""
213
214    environment = Directory('.', [
215        File('a.vert',
216             """#version 140
217             #define BODY {}
218             #include "subdir/a"
219             void afun()BODY
220             """),
221        Directory('subdir', [File('a', 'void main() BODY\n')])])
222
223    glslc_args = ['a.vert']
224
225@inside_glslc_testsuite('Include')
226class VerifyIncludeDeepSubdir(expect.StdoutMatch):
227    """Tests #including a file from a subdirectory nested a few levels down."""
228
229    environment = Directory('.', [
230        File('a.vert',
231             '#version 140\ncontent a1\n#include "dir/subdir/subsubdir/a"\ncontent a2\n'),
232        Directory('dir', [
233            Directory('subdir', [
234                Directory('subsubdir', [File('a', 'content incl\n')])])])])
235
236    glslc_args = ['-E', 'a.vert']
237
238    expected_stdout = \
239"""#version 140
240#extension GL_GOOGLE_include_directive : enable
241#line 0 "a.vert"
242
243content a1
244#line 0 "dir/subdir/subsubdir/a"
245 content incl
246#line 3 "a.vert"
247 content a2
248"""
249
250@inside_glslc_testsuite('Include')
251class VerifyCompileIncludeDeepSubdir(expect.ValidObjectFile):
252    """Tests #including a file from a subdirectory nested a few levels down
253       via full compilation."""
254
255    environment = Directory('.', [
256        File('a.vert',
257             """#version 140
258             #define BODY {}
259             #include "dir/subdir/subsubdir/a"
260             void afun()BODY
261             """),
262        Directory('dir', [
263            Directory('subdir', [
264                Directory('subsubdir', [File('a', 'void main() BODY\n')])])])])
265
266    glslc_args = ['a.vert']
267
268
269@inside_glslc_testsuite('Include')
270class TestWrongPoundVersionInIncludingFile(expect.ValidObjectFileWithWarning):
271    """Tests that warning message for #version directive in the including file
272    has the correct filename."""
273
274    environment = Directory('.', [
275        File('a.vert', '#version 100000000\n#include "b.glsl"\n'),
276        File('b.glsl', 'void main() {}\n')])
277    glslc_args = ['-c', '-std=400', 'a.vert']
278
279    expected_warning = [
280        'a.vert: warning: (version, profile) forced to be (400, none),'
281        ' while in source code it is (100000000, none)\n'
282        '1 warning generated.\n'
283    ]
284
285
286# TODO(antiagainst): now #version in included files results in an error.
287# Fix this after #version in included files are supported.
288# TODO(dneto): I'm not sure what the expected result should be.
289@inside_glslc_testsuite('Include')
290class TestWrongPoundVersionInIncludedFile(expect.ErrorMessage):
291    """Tests that warning message for #version directive in the included file
292    has the correct filename."""
293
294    environment = Directory('.', [
295        File('a.vert', '#version 140\n#include "b.glsl"\nvoid main() {}'),
296        File('b.glsl', '#version 10000000\n')])
297    glslc_args = ['-E', 'a.vert']
298
299    expected_error = [
300        "b.glsl:1: error: '#version' : must occur first in shader\n",
301        '1 error generated.\n'
302    ]
303
304
305@inside_glslc_testsuite('Include')
306class VerifyRelativeInclude(expect.StdoutMatch):
307    """Tests #including a relative sibling."""
308
309    environment = Directory('.', [
310        File('a.vert', '#version 140\ncontent a\n#include "foo/b.glsl"\n'),
311        Directory('foo', [
312            File('b.glsl', '#include "c.glsl"\ncontent b\n'),
313            File('c.glsl', 'content c\n')
314        ])])
315
316    glslc_args = ['-E', 'a.vert']
317
318    expected_stdout = \
319"""#version 140
320#extension GL_GOOGLE_include_directive : enable
321#line 0 "a.vert"
322
323content a
324#line 0 "foo/b.glsl"
325#line 0 "foo/c.glsl"
326 content c
327#line 1 "foo/b.glsl"
328 content b
329#line 3 "a.vert"
330
331"""
332
333@inside_glslc_testsuite('Include')
334class VerifyNestedRelativeInclude(expect.StdoutMatch):
335    """Tests #including a relative child file."""
336
337    environment = Directory('.', [
338        File('a.vert', '#version 140\ncontent a\n#include "foo/b.glsl"\n'),
339        Directory('foo', [
340            File('b.glsl', '#include "bar/c.glsl"\ncontent b\n'),
341            Directory('bar', [
342                File('c.glsl', 'content c\n')
343            ])
344        ])
345    ])
346
347    glslc_args = ['-E', 'a.vert']
348
349    expected_stdout = \
350"""#version 140
351#extension GL_GOOGLE_include_directive : enable
352#line 0 "a.vert"
353
354content a
355#line 0 "foo/b.glsl"
356#line 0 "foo/bar/c.glsl"
357 content c
358#line 1 "foo/b.glsl"
359 content b
360#line 3 "a.vert"
361
362"""
363
364
365@inside_glslc_testsuite('Include')
366class VerifyRelativeIncludeWithDashI(expect.StdoutMatch):
367    """Tests #including a relative file from a -I directory."""
368
369    environment = Directory('.', [
370        File('a.vert', '#version 140\ncontent a\n#include "bar/b.glsl"\n'),
371        Directory('foo', [
372            Directory('bar', [
373                File('b.glsl', '#include "c.glsl"\ncontent b\n'),
374            ]),
375            File('c.glsl', 'content c\n')
376        ])
377    ])
378
379    glslc_args = ['-E', 'a.vert', '-Ifoo']
380
381    expected_stdout = \
382"""#version 140
383#extension GL_GOOGLE_include_directive : enable
384#line 0 "a.vert"
385
386content a
387#line 0 "foo/bar/b.glsl"
388#line 0 "foo/c.glsl"
389 content c
390#line 1 "foo/bar/b.glsl"
391 content b
392#line 3 "a.vert"
393
394"""
395
396
397@inside_glslc_testsuite('Include')
398class VerifyRelativeOverridesDashI(expect.StdoutMatch):
399    """Tests that relative includes override -I parameters."""
400
401    environment = Directory('.', [
402        File('a.vert', '#version 140\ncontent a\n#include "b.glsl"\n'),
403        File('b.glsl', 'content base_b\n'),
404        Directory('foo', [
405            File('b.glsl', '#include "c.glsl"\ncontent b\n'),
406            File('c.glsl', 'content c\n')
407        ])
408    ])
409
410    glslc_args = ['-E', 'a.vert', '-Ifoo']
411
412    expected_stdout = \
413"""#version 140
414#extension GL_GOOGLE_include_directive : enable
415#line 0 "a.vert"
416
417content a
418#line 0 "b.glsl"
419 content base_b
420#line 3 "a.vert"
421
422"""
423
424
425@inside_glslc_testsuite('Include')
426class VerifyRelativeParent(expect.StdoutMatch):
427    """Tests #including a parent file."""
428
429    environment = Directory('.', [
430        File('a.vert', '#version 140\ncontent a\n#include "b.glsl"\n'),
431        File('c.glsl', 'content c\n'),
432        Directory('foo', [
433            File('b.glsl', '#include "../c.glsl"\ncontent b\n')
434        ])
435    ])
436
437    glslc_args = ['-E', 'a.vert', '-Ifoo']
438
439    expected_stdout = \
440"""#version 140
441#extension GL_GOOGLE_include_directive : enable
442#line 0 "a.vert"
443
444content a
445#line 0 "foo/b.glsl"
446#line 0 "foo/../c.glsl"
447 content c
448#line 1 "foo/b.glsl"
449 content b
450#line 3 "a.vert"
451
452"""
453
454
455@inside_glslc_testsuite('Include')
456class VerifyRelativeNeighbourDirectory(expect.StdoutMatch):
457    """Tests #including a relative file in a neighbour directory."""
458
459    environment = Directory('.', [
460        File('a.vert', '#version 140\ncontent a\n#include "foo/b.glsl"\n'),
461        Directory('foo', [
462            File('b.glsl', '#include "../bar/c.glsl"\ncontent b\n')
463        ]),
464        Directory('bar', [
465            File('c.glsl', 'content c\n')
466        ])
467    ])
468
469    glslc_args = ['-E', 'a.vert']
470
471    expected_stdout = \
472"""#version 140
473#extension GL_GOOGLE_include_directive : enable
474#line 0 "a.vert"
475
476content a
477#line 0 "foo/b.glsl"
478#line 0 "foo/../bar/c.glsl"
479 content c
480#line 1 "foo/b.glsl"
481 content b
482#line 3 "a.vert"
483
484"""
485
486
487@inside_glslc_testsuite('Include')
488class VerifyRelativeOnlyToSelf(expect.ErrorMessage):
489    """Tests that a relative includes are only relative to yourself."""
490
491    environment = Directory('.', [
492        File('a.vert', '#version 140\ncontent a\n#include "foo/b.glsl"\n'),
493        File('c.glsl', 'content c\n'),
494        Directory('foo', [
495            File('b.glsl', '#include "c.glsl"\ncontent b\n')
496        ]),
497    ])
498
499    glslc_args = ['-E', 'a.vert']
500
501    expected_error = [
502        "foo/b.glsl:1: error: '#include' : "
503        'Cannot find or open include file. for header name: c.glsl\n',
504        '1 error generated.\n'
505    ]
506
507
508@inside_glslc_testsuite('Include')
509class VerifyRelativeFromAbsolutePath(expect.StdoutMatch):
510    """Tests that absolute files can relatively include."""
511
512    environment = Directory('.', [
513        File('a.vert', '#version 140\ncontent a\n#include "b.glsl"\n'),
514        File('b.glsl', 'content b\n')
515    ])
516
517    glslc_args = ['-E', SpecializedString('$directory/a.vert')]
518
519    expected_stdout = SpecializedString(
520"""#version 140
521#extension GL_GOOGLE_include_directive : enable
522#line 0 "$directory/a.vert"
523
524content a
525#line 0 "$directory/b.glsl"
526 content b
527#line 3 "$directory/a.vert"
528
529""")
530
531
532@inside_glslc_testsuite('Include')
533class VerifyDashIAbsolutePath(expect.StdoutMatch):
534    """Tests that -I parameters can be absolute paths."""
535
536    environment = Directory('.', [
537        File('a.vert', '#version 140\ncontent a\n#include "b.glsl"\n'),
538        Directory('foo', {
539            File('b.glsl', 'content b\n')
540        })
541    ])
542
543    glslc_args = ['-E', 'a.vert', '-I', SpecializedString('$directory/foo')]
544
545    expected_stdout = SpecializedString(
546"""#version 140
547#extension GL_GOOGLE_include_directive : enable
548#line 0 "a.vert"
549
550content a
551#line 0 "$directory/foo/b.glsl"
552 content b
553#line 3 "a.vert"
554
555""")
556