# Copyright 2015 The Shaderc Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import expect
import os.path
from environment import File, Directory
from glslc_test_framework import inside_glslc_testsuite
from placeholder import FileShader
from glslc_test_framework import GlslCTest

MINIMAL_SHADER = '#version 140\nvoid main() {}'
EMPTY_SHADER_IN_CURDIR = Directory('.', [File('shader.vert', MINIMAL_SHADER)])
EMPTY_SHADER_IN_SUBDIR = Directory('subdir',
                                   [File('shader.vert', MINIMAL_SHADER)])


def process_test_specified_dependency_info_rules(test_specified_rules):
    """A helper function to process the expected dependency info rules
    specified in tests before checking the actual dependency rule output.

    This is required because the filename and path of temporary files created
    through FileShader is unknown at the time the expected dependency info rules
    are declared.

    Note this function process the given rule list in-place.
    """
    for rule in test_specified_rules:
        # If the 'target' value is not a hard-coded file name but a
        # FileShader, we need its full path, append extension to it and
        # strip the directory component from it to get the complete target
        # name.
        if isinstance(rule['target'], FileShader):
            rule['target'] = rule['target'].filename
        if 'target_extension' in rule:
            if rule['target_extension'] is not None:
                rule['target'] = rule['target'] + rule['target_extension']
            rule.pop('target_extension')
        rule['target'] = os.path.basename(rule['target'])

        # The dependency set may have FileShader too, we need to replace
        # them with their absolute paths.
        dependent_file_name_set = set()
        for dependent_file in rule['dependency']:
            if isinstance(dependent_file, FileShader):
                dependent_file_name_set.add(dependent_file.filename)
            else:
                dependent_file_name_set.add(dependent_file)
        rule['dependency'] = dependent_file_name_set


def parse_text_rules(text_lines):
    """ A helper function to read text lines and construct and returns a list of
    dependency rules which can be used for comparison.

    The list is built with the text order.  Each rule is described in the
    following way:
        {'target': <target name>, 'dependency': <set of dependent filenames>}
    """
    rules = []
    for line in text_lines:
        if line.strip() == "":
            continue
        rule = {'target': line.split(': ')[0].strip(),
                'dependency': set(line.split(': ')[-1].strip().split(' '))}
        rules.append(rule)
    return rules


class DependencyInfoStdoutMatch(GlslCTest):
    """Mixin class for tests that can expect dependency info in Stdout.

    To mix in this class, the subclass needs to provide
    dependency_rules_expected as a list of dictionaries, each dictionary
    describes one expected make rule for a target file. A expected rule should
    be specified in the following way:

        rule = {'target': <target name>,
                'target_extension': <.spv, .spvasm or None>,
                'dependency': <dependent file names>}

        The 'target_extension' field is optional, its value will be appended to
        'target' to get complete target name.

    And the list 'dependency_rules_expected' is a list of such rules and the
    order of the rules does matter.
    """

    def check_stdout_dependency_info(self, status):
        if not status.stdout:
            return False, 'Expect dependency rules on stdout'

        rules = parse_text_rules(status.stdout.split('\n'))

        process_test_specified_dependency_info_rules(
            self.dependency_rules_expected)

        if self.dependency_rules_expected != rules:
            return False, ('Incorrect dependency info:\n{ac_rules}\n'
                           'Expected:\n{ex_rules}\n'
                           'Stdout output:\n{ac_stdout}\n'.format(
                               ac_rules=rules,
                               ex_rules=self.dependency_rules_expected,
                               ac_stdout=status.stdout))
        return True, ''


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputRelativePathNoInclude(DependencyInfoStdoutMatch):
    """Tests -M with single input file which doesn't contain #include and is
    represented in relative path.
    e.g. glslc -M shader.vert
      => shader.vert.spv: shader.vert
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-M', 'shader.vert']
    dependency_rules_expected = [{'target': "shader.vert.spv",
                                  'dependency': {"shader.vert"}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputAbsolutePathNoInclude(DependencyInfoStdoutMatch):
    """Tests -M with single input file which doesn't contain #include and is
    represented in absolute path.
    e.g. glslc -M /usr/local/shader.vert
      => shader.vert.spv: /usr/local/shader.vert
    """
    shader = FileShader(MINIMAL_SHADER, '.vert')
    glslc_args = ['-M', shader]
    dependency_rules_expected = [{'target': shader,
                                  'target_extension': '.spv',
                                  'dependency': {shader}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputRelativePathWithInclude(
        DependencyInfoStdoutMatch):
    """Tests -M with single input file which does contain #include and is
    represented in relative path.
    e.g. glslc -M a.vert
      => a.vert.spv: a.vert b.vert
    """
    environment = Directory('.', [
        File('a.vert', '#version 140\n#include "b.vert"\nvoid main(){}\n'),
        File('b.vert', 'void foo(){}\n'),
    ])
    glslc_args = ['-M', 'a.vert']
    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency': {'a.vert', 'b.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputRelativePathWithIncludeSubdir(
        DependencyInfoStdoutMatch):
    """Tests -M with single input file which does #include another file in a
    subdirectory of current directory and is represented in relative path.
    e.g. glslc -M a.vert
      => a.vert.spv: a.vert include/b.vert
    """
    environment = Directory('.', [
        File('a.vert', ('#version 140\n#include "include/b.vert"'
                        '\nvoid main(){}\n')),
        Directory('include', [File('b.vert', 'void foo(){}\n')]),
    ])
    glslc_args = ['-M', 'a.vert']
    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency': {'a.vert', 'include/b.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputRelativePathWithDashI(DependencyInfoStdoutMatch):
    """Tests -M with single input file works with -I option. The #include
    directive does not specify 'include/' for the file to be include.
    e.g. glslc -M a.vert -I include
      => a.vert.spv: a.vert include/b.vert
    """
    environment = Directory('.', [
        File('a.vert', ('#version 140\n#include "b.vert"'
                        '\nvoid main(){}\n')),
        Directory('include', [File('b.vert', 'void foo(){}\n')]),
    ])
    glslc_args = ['-M', 'a.vert', '-I', 'include']
    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency': {'a.vert', 'include/b.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputRelativePathWithNestedInclude(
        DependencyInfoStdoutMatch):
    """Tests -M with single input file under nested #include case. The input file
    is represented in relative path.
    e.g. glslc -M a.vert
      => a.vert.spv: a.vert b.vert c.vert
    """
    environment = Directory('.', [
        File('a.vert', '#version 140\n#include "b.vert"\nvoid main(){}\n'),
        File('b.vert', 'void foo(){}\n#include "c.vert"\n'),
        File('c.vert', 'void bar(){}\n'),
    ])
    glslc_args = ['-M', 'a.vert']

    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency':
                                  {'a.vert', 'b.vert', 'c.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMMultipleInputRelativePathNoInclude(
        DependencyInfoStdoutMatch):
    """Tests -M with multiple input file which don't contain #include and are
    represented in relative paths.
    e.g. glslc -M a.vert b.vert
      => a.vert.spv: a.vert
         b.vert.spv: b.vert
    """
    environment = Directory('.', [
        File('a.vert', MINIMAL_SHADER),
        File('b.vert', MINIMAL_SHADER),
    ])
    glslc_args = ['-M', 'a.vert', 'b.vert']

    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency': {'a.vert'}},
                                 {'target': 'b.vert.spv',
                                  'dependency': {'b.vert'}}, ]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMMultipleInputAbsolutePathNoInclude(
        DependencyInfoStdoutMatch):
    """Tests -M with single input file which doesn't contain #include and is
    represented in absolute path.
    e.g. glslc -M /usr/local/a.vert /usr/local/b.vert
      => a.vert.spv: /usr/local/a.vert
         b.vert.spv: /usr/local/b.vert
    """
    shader_a = FileShader(MINIMAL_SHADER, '.vert')
    shader_b = FileShader(MINIMAL_SHADER, '.vert')
    glslc_args = ['-M', shader_a, shader_b]

    dependency_rules_expected = [{'target': shader_a,
                                  'target_extension': '.spv',
                                  'dependency': {shader_a}},
                                 {'target': shader_b,
                                  'target_extension': '.spv',
                                  'dependency': {shader_b}}, ]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDashCapMT(DependencyInfoStdoutMatch):
    """Tests -MT works with -M. User can specify the target object name in the
    generated dependency info.
    e.g. glslc -M shader.vert -MT target
      => target: shader.vert
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-M', 'shader.vert', '-MT', 'target']
    dependency_rules_expected = [{'target': 'target',
                                  'dependency': {'shader.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMInputAbsolutePathWithInclude(DependencyInfoStdoutMatch):
    """Tests -M have included files represented in absolute paths when the input
    file is represented in absolute path.
    E.g. Assume a.vert has '#include "b.vert"'
         glslc -M /usr/local/a.vert
      => a.vert.spv: /usr/local/a.vert /usr/local/b.vert
    """
    environment = Directory('.', [File('b.vert', 'void foo(){}\n')])
    shader_main = FileShader(
        '#version 140\n#include "b.vert"\nvoid main(){}\n', '.vert')

    glslc_args = ['-M', shader_main]
    dependency_rules_expected = [{
        'target': shader_main,
        'target_extension': '.spv',
        'dependency': {shader_main}
        # The dependency here is not complete.  we can not get the absolute path
        # of b.vert here. It will be added in check_stdout_dependency_info()
    }]

    def check_stdout_dependency_info(self, status):
        # Add the absolute path of b.vert to the dependency set
        self.dependency_rules_expected[0]['dependency'].add(os.path.dirname(
            self.shader_main.filename) + '/b.vert')
        return DependencyInfoStdoutMatch.check_stdout_dependency_info(self,
                                                                      status)


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMSingleInputAbsolutePathWithIncludeSubdir(
        DependencyInfoStdoutMatch):
    """Tests -M with single input file which does #include another file in a
    subdirectory of current directory and is represented in absolute path.
    e.g. glslc -M /usr/local/a.vert
      => a.vert.spv: /usr/local/a.vert /usr/local/include/b.vert
    """
    environment = Directory('.', [
        Directory('include', [File('b.vert', 'void foo(){}\n')]),
    ])
    shader_main = FileShader('#version 140\n#include "include/b.vert"',
                             '.vert')
    glslc_args = ['-M', shader_main]
    dependency_rules_expected = [{
        'target': shader_main,
        'target_extension': '.spv',
        'dependency': {shader_main}
        # The dependency here is not complete.  we can not get the absolute
        # path of include/b.vert here. It will be added in
        # check_stdout_dependency_info()
    }]

    def check_stdout_dependency_info(self, status):
        # Add the absolute path of include/b.vert to the dependency set
        self.dependency_rules_expected[0]['dependency'].add(os.path.dirname(
            self.shader_main.filename) + '/include/b.vert')
        return DependencyInfoStdoutMatch.check_stdout_dependency_info(self,
                                                                      status)


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMOverridesOtherModes(DependencyInfoStdoutMatch):
    """Tests -M overrides other compiler mode options, includeing -E, -c and -S.
    """
    environment = Directory('.', [
        File('a.vert', MINIMAL_SHADER),
        File('b.vert', MINIMAL_SHADER),
    ])
    glslc_args = ['-M', '-E', '-c', '-S', 'a.vert', 'b.vert']
    dependency_rules_expected = [{'target': 'a.vert.spv',
                                  'dependency': {'a.vert'}},
                                 {'target': 'b.vert.spv',
                                  'dependency': {'b.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMMEquivalentToCapM(DependencyInfoStdoutMatch):
    """Tests that -MM behaves as -M.
    e.g. glslc -MM shader.vert
      => shader.vert.spv: shader.vert
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MM', 'shader.vert']
    dependency_rules_expected = [{'target': 'shader.vert.spv',
                                  'dependency': {'shader.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMImpliesDashCapE(DependencyInfoStdoutMatch,
                                  expect.NoOutputOnStderr):
    """Tests that -M implies -E, a .glsl file without an explict stage should
    not generate an error.
    e.g. glslc -M shader.glsl
      => shader.spv: shader.glsl
         <no error message should be generated>
    """
    environment = Directory('.', [File('shader.glsl', MINIMAL_SHADER)])
    glslc_args = ['-M', 'shader.glsl']
    dependency_rules_expected = [{'target': 'shader.spv',
                                  'dependency': {'shader.glsl'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMImpliesDashW(DependencyInfoStdoutMatch,
                               expect.NoOutputOnStderr):
    """Tests that -M implies -w, a deprecated attribute should not generate
    warning message.
    e.g. glslc -M shader.vert
      => shader.vert.spv: shader.vert
         <no warning message should be generated>
    """
    environment = Directory('.', [File(
        'shader.vert', '#version 140\nattribute float x;\nvoid main() {}')])
    glslc_args = ['-M', 'shader.vert']
    dependency_rules_expected = [{'target': 'shader.vert.spv',
                                  'dependency': {'shader.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMMImpliesDashCapE(DependencyInfoStdoutMatch,
                                   expect.NoOutputOnStderr):
    """Tests that -M implies -E, a .glsl file without an explict stage should
    not generate an error.
    e.g. glslc -MM shader.glsl
      => shader.spv: shader.glsl
         <no error message should be generated>
    """
    environment = Directory('.', [File('shader.glsl', MINIMAL_SHADER)])
    glslc_args = ['-MM', 'shader.glsl']
    dependency_rules_expected = [{'target': 'shader.spv',
                                  'dependency': {'shader.glsl'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMMImpliesDashW(DependencyInfoStdoutMatch,
                                expect.NoOutputOnStderr):
    """Tests that -MM implies -w, a deprecated attribute should not generate
    warning message.
    e.g. glslc -MM shader.vert
      => shader.vert.spv: shader.vert
         <no warning message should be generated>
    """
    environment = Directory('.', [File(
        'shader.vert', '#version 140\nattribute float x;\nvoid main() {}')])
    glslc_args = ['-MM', 'shader.vert']
    dependency_rules_expected = [{'target': 'shader.vert.spv',
                                  'dependency': {'shader.vert'}}]


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMD(expect.ValidFileContents, expect.ValidNamedObjectFile):
    """Tests that -MD generates dependency info file and compilation output.
    e.g. glslc -MD shader.vert
      => <a.spv: valid SPIR-V object file>
      => <shader.vert.spv.d: dependency info>
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MD', 'shader.vert']
    expected_object_filenames = ('a.spv', )
    target_filename = 'shader.vert.spv.d'
    expected_file_contents = ['shader.vert.spv: shader.vert\n']


class DependencyInfoFileMatch(GlslCTest):
    """Mixin class for tests that can expect dependency info files.

    To mix in this class, subclasses need to provide dependency_info_filenames
    and dependency_info_files_expected_contents which are two lists.
    list dependency_info_filenames contains the dependency info file names and
    list dependency_info_files_expected_contents contains the expected matching
    dependency rules.
    The item order of the two lists should match, which means:
        dependency_info_files_expected_contents[i] should describe the
        dependency rules saved in dependency_info_filenames[i]

    The content of each dependency info file is described in same 'list of dict'
    structure explained in class DependencyInfoStdoutMatch's doc string.
    """

    def check_dependency_info_files(self, status):
        dep_info_files = \
            [os.path.join(status.directory,
                          f) for f in self.dependency_info_filenames]
        for i, df in enumerate(dep_info_files):
            if not os.path.isfile(df):
                return False, 'Cannot find file: ' + df
            try:
                with open(df, 'r') as dff:
                    content = dff.read()
                    rules = parse_text_rules(content.split('\n'))

                    process_test_specified_dependency_info_rules(
                        self.dependency_info_files_expected_contents[i])

                    if self.dependency_info_files_expected_contents[
                            i] != rules:
                        return False, (
                            'Incorrect dependency info:\n{ac_rules}\n'
                            'Expected:\n{ex_rules}\n'
                            'Incorrect file output:\n{ac_out}\n'
                            'Incorrect dependency info file:\n{ac_file}\n'.format(
                                ac_rules=rules,
                                ex_rules=self.dependency_rules_expected,
                                ac_stdout=content,
                                ac_file=df))
            except IOError:
                return False, ('Could not open dependency info file ' + df +
                               ' for reading')
        return True, ''


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMWorksWithDashO(DependencyInfoFileMatch):
    """Tests -M works with -o option. When user specifies an output file name
    with -o, the dependency info should be dumped to the user specified output
    file.
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-M', 'shader.vert', '-o', 'dep_info']
    dependency_info_filenames = ('dep_info', )
    dependency_info_files_expected_contents = []
    dependency_info_files_expected_contents.append(
        [{'target': 'shader.vert.spv',
          'dependency': {'shader.vert'}}])


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDMultipleFile(expect.ValidNamedObjectFile,
                                DependencyInfoFileMatch):
    """Tests that -MD generates dependency info file for multiple files.
    e.g. glslc -MD a.vert b.vert -c
      => <a.vert.spv: valid SPIR-V object file>
      => <a.vert.spv.d: dependency info: "a.vert.spv: a.vert">
      => <b.vert.spv: valid SPIR-V object file>
      => <b.vert.spv.d: dependency info: "b.vert.spv: b.vert">
    """
    environment = Directory('.', [File('a.vert', MINIMAL_SHADER),
                                  File('b.vert', MINIMAL_SHADER)])
    glslc_args = ['-MD', 'a.vert', 'b.vert', '-c']
    expected_object_filenames = ('a.vert.spv', 'b.vert.spv', )

    dependency_info_filenames = ['a.vert.spv.d', 'b.vert.spv.d']
    dependency_info_files_expected_contents = []
    dependency_info_files_expected_contents.append([{'target': 'a.vert.spv',
                                                     'dependency': {'a.vert'}}
                                                    ])
    dependency_info_files_expected_contents.append([{'target': 'b.vert.spv',
                                                     'dependency': {'b.vert'}}
                                                    ])


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDMultipleFilePreprocessingOnlyMode(expect.StdoutMatch,
                                                     DependencyInfoFileMatch):
    """Tests that -MD generates dependency info file for multiple files in
    preprocessing only mode.
    e.g. glslc -MD a.vert b.vert -E
      => stdout: preprocess result of a.vert and b.vert
      => <a.vert.spv.d: dependency info: "a.vert.spv: a.vert">
      => <b.vert.spv.d: dependency info: "b.vert.spv: b.vert">
    """
    environment = Directory('.', [File('a.vert', MINIMAL_SHADER),
                                  File('b.vert', MINIMAL_SHADER)])
    glslc_args = ['-MD', 'a.vert', 'b.vert', '-E']
    dependency_info_filenames = ['a.vert.spv.d', 'b.vert.spv.d']
    dependency_info_files_expected_contents = []
    dependency_info_files_expected_contents.append([{'target': 'a.vert.spv',
                                                     'dependency': {'a.vert'}}
                                                    ])
    dependency_info_files_expected_contents.append([{'target': 'b.vert.spv',
                                                     'dependency': {'b.vert'}}
                                                    ])
    expected_stdout = ("#version 140\nvoid main(){ }\n"
                       "#version 140\nvoid main(){ }\n")


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDMultipleFileDisassemblyMode(expect.ValidNamedAssemblyFile,
                                               DependencyInfoFileMatch):
    """Tests that -MD generates dependency info file for multiple files in
    disassembly mode.
    e.g. glslc -MD a.vert b.vert -S
      => <a.vert.spvasm: valid SPIR-V assembly file>
      => <a.vert.spvasm.d: dependency info: "a.vert.spvasm: a.vert">
      => <b.vert.spvasm: valid SPIR-V assembly file>
      => <b.vert.spvasm.d: dependency info: "b.vert.spvasm: b.vert">
    """
    environment = Directory('.', [File('a.vert', MINIMAL_SHADER),
                                  File('b.vert', MINIMAL_SHADER)])
    glslc_args = ['-MD', 'a.vert', 'b.vert', '-S']
    expected_assembly_filenames = ('a.vert.spvasm', 'b.vert.spvasm', )
    dependency_info_filenames = ['a.vert.spvasm.d', 'b.vert.spvasm.d']

    dependency_info_files_expected_contents = []
    dependency_info_files_expected_contents.append([{'target': 'a.vert.spvasm',
                                                     'dependency': {'a.vert'}}
                                                    ])
    dependency_info_files_expected_contents.append([{'target': 'b.vert.spvasm',
                                                     'dependency': {'b.vert'}}
                                                    ])


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMT(expect.ValidFileContents, expect.ValidNamedObjectFile):
    """Tests that -MT generates dependency info file with specified target label.
    e.g. glslc -MD shader.vert -MT target_label
      => <a.spv: valid SPIR-V object file>
      => <shader.vert.spv.d: dependency info: "target_label: shader.vert">
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MD', 'shader.vert', '-MT', 'target_label']
    expected_object_filenames = ('a.spv', )
    target_filename = 'shader.vert.spv.d'
    expected_file_contents = ['target_label: shader.vert\n']


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMF(expect.ValidFileContents, expect.ValidNamedObjectFile):
    """Tests that -MF dumps dependency info into specified file.
    e.g. glslc -MD shader.vert -MF dep_file
      => <a.spv: valid SPIR-V object file>
      => <dep_file: dependency info: "shader.vert.spv: shader.vert">
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MD', 'shader.vert', '-MF', 'dep_file']
    expected_object_filenames = ('a.spv', )
    target_filename = 'dep_file'
    expected_file_contents = ['shader.vert.spv: shader.vert\n']


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDSpecifyOutputFileName(expect.ValidFileContents,
                                         expect.ValidNamedObjectFile):
    """Tests that -MD has the default dependency info file name and target
    label correct when -o <output_file_name> appears in the command line.
    The default dependency info file name and target label should be deduced
    from the linking-disabled compilation output.
    e.g. glslc -MD subdir/shader.vert -c -o output
      => <./output: valid SPIR-V object file>
      => <./output.d: dependency info: "output: shader.vert">
    """
    environment = EMPTY_SHADER_IN_SUBDIR
    glslc_args = ['-MD', 'subdir/shader.vert', '-c', '-o', 'output']
    expected_object_filenames = ('output', )
    target_filename = 'output.d'
    expected_file_contents = ['output: subdir/shader.vert\n']


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDWithDashMFDashMTDashO(expect.ValidFileContents,
                                         expect.ValidNamedObjectFile):
    """Tests that -MD, -MF, -MT and -o gernates dependency info file and
    compilation output file correctly
    e.g. glslc -MD subdir/shader.vert -c -o subdir/out -MF dep_info -MT label
      => <subdir/out: valid SPIR-V object file>
      => <dep_info: dependency info: "label: shader.vert">
    """
    environment = EMPTY_SHADER_IN_SUBDIR
    glslc_args = ['-MD', 'subdir/shader.vert', '-c', '-o', 'subdir/out', '-MF',
                  'dep_info', '-MT', 'label']
    expected_object_filenames = ('subdir/out', )
    target_filename = 'dep_info'
    expected_file_contents = ['label: subdir/shader.vert\n']


@inside_glslc_testsuite('OptionsCapM')
class TestDashCapMDWithDashMFDashMTDashODisassemblyMode(
        expect.ValidFileContents, expect.ValidNamedAssemblyFile):
    """Tests that -MD, -MF, -MT and -o gernates dependency info file and
    compilation output file correctly in disassembly mode
    e.g. glslc -MD subdir/shader.vert -s -o subdir/out -MF dep_info -MT label
      => <subdir/out: valid SPIR-V object file>
      => <dep_info: dependency info: "label: shader.vert">
    """
    environment = EMPTY_SHADER_IN_SUBDIR
    glslc_args = ['-MD', 'subdir/shader.vert', '-S', '-o', 'subdir/out', '-MF',
                  'dep_info', '-MT', 'label']
    expected_assembly_filenames = ('subdir/out', )
    target_filename = 'dep_info'
    expected_file_contents = ['label: subdir/shader.vert\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorSetBothDashCapMAndDashCapMD(expect.StderrMatch):
    """Tests that when both -M (or -MM) and -MD are specified, glslc should exit
    with an error message complaining the case and neither dependency info
    output nor compilation output. This test has -MD before -M flag.
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MD', '-M', 'shader.vert']
    expected_stderr = ['glslc: error: both -M (or -MM) and -MD are specified. '
                       'Only one should be used at one time.\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorSetBothDashCapMDAndDashCapM(expect.StderrMatch):
    """Tests that when both -M (or -MM) and -MD are specified, glslc should exit
    with an error message complaining the case and neither dependency info
    output nor compilation output. This test has -M before -MD flag.
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-M', '-MD', 'shader.vert']
    expected_stderr = ['glslc: error: both -M (or -MM) and -MD are specified. '
                       'Only one should be used at one time.\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorDashCapMFWithMultipleInputFiles(expect.StderrMatch):
    """Tests that when -MF option is specified, only one input file should be
    provided."""
    environment = Directory('.', [File('a.vert', MINIMAL_SHADER),
                                  File('b.vert', MINIMAL_SHADER)])
    glslc_args = ['-MD', 'a.vert', 'b.vert', '-c', '-MF', 'dep_info']
    expected_stderr = ['glslc: error: '
                       'to specify dependency info file name or dependency '
                       'info target, only one input file is allowed.\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorDashCapMTWithMultipleInputFiles(expect.StderrMatch):
    """Tests that when -MT option is specified, only one input file should be
    provided."""
    environment = Directory('.', [File('a.vert', MINIMAL_SHADER),
                                  File('b.vert', MINIMAL_SHADER)])
    glslc_args = ['-M', 'a.vert', 'b.vert', '-c', '-MT', 'target']
    expected_stderr = ['glslc: error: '
                       'to specify dependency info file name or dependency '
                       'info target, only one input file is allowed.\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorDashCapMFMissingDashMAndDashMD(expect.StderrMatch):
    """Tests that when only -MF is specified while -M and -MD are not specified,
    glslc should emit an error complaining that the user must specifiy either
    -M (-MM) or -MD to generate dependency info.
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MF', 'dep_info', 'shader.vert', '-c']
    expected_stderr = ['glslc: error: '
                       'to generate dependencies you must specify either -M '
                       '(-MM) or -MD\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorDashCapMTMissingDashMAndMDWith(expect.StderrMatch):
    """Tests that when only -MF and -MT is specified while -M and -MD are not
    specified, glslc should emit an error complaining that the user must
    specifiy either -M (-MM) or -MD to generate dependency info.
    """
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['-MF', 'dep_info', '-MT', 'target', 'shader.vert', '-c']
    expected_stderr = ['glslc: error: '
                       'to generate dependencies you must specify either -M '
                       '(-MM) or -MD\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorMissingDependencyInfoFileName(expect.StderrMatch):
    """Tests that dependency file name is missing when -MF is specified."""
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['target', 'shader.vert', '-c', '-MF']
    expected_stderr = ['glslc: error: '
                       'missing dependency info filename after \'-MF\'\n']


@inside_glslc_testsuite('OptionsCapM')
class TestErrorMissingDependencyTargetName(expect.StderrMatch):
    """Tests that dependency target name is missing when -MT is specified."""
    environment = EMPTY_SHADER_IN_CURDIR
    glslc_args = ['target', 'shader.vert', '-c', '-MT']
    expected_stderr = ['glslc: error: '
                       'missing dependency info target after \'-MT\'\n']
