# Copyright 2016 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
from glslc_test_framework import inside_glslc_testsuite
import re

@inside_glslc_testsuite('OptionDashDashVersion')
class TestVersionContainsShaderc(expect.StdoutMatch, expect.ReturnCodeIsZero):
    """Tests --version output contains 'shaderc'."""
    glslc_args = ['--version']
    expected_stdout = re.compile('^shaderc')


@inside_glslc_testsuite('OptionDashDashVersion')
class TestVersionContainsSpirvTools(expect.StdoutMatch, expect.ReturnCodeIsZero):
    """Tests --version output contains 'spirv-tools'."""
    glslc_args = ['--version']
    expected_stdout = re.compile('\nspirv-tools')


@inside_glslc_testsuite('OptionDashDashVersion')
class TestVersionContainsGlslang(expect.StdoutMatch, expect.ReturnCodeIsZero):
    """Tests --version output contains 'glslang'."""
    glslc_args = ['--version']
    expected_stdout = re.compile('\nglslang')


@inside_glslc_testsuite('OptionDashDashVersion')
class TestVersionContainsTarget(expect.StdoutMatch, expect.ReturnCodeIsZero):
    """Tests --version output contains 'Target:'."""
    glslc_args = ['--version']
    expected_stdout = re.compile('\nTarget: SPIR-V \d+\.\d+')
