]> git.tdb.fi Git - libs/gl.git/blobdiff - tests/glsl/glslcompiler.cpp
Make the GLSL compiler test runner able to verify non-error diagnostics
[libs/gl.git] / tests / glsl / glslcompiler.cpp
index 0fd0855489d63ca4f6a5de05c30c0615a9307c89..01c1fba28e2e4fe90d0f2268a485538fd671f258 100644 (file)
@@ -17,7 +17,10 @@ protected:
                Msp::GL::SL::Compiler::Mode compile_mode;
                std::map<std::string, int> spec_values;
                std::map<Msp::GL::SL::Stage::Type, std::string> expected_output;
-               std::string expected_error;
+               std::string expected_diagnostic;
+               bool expect_success;
+
+               TestCase(): expect_success(true) { }
        };
 
        std::list<TestCase> test_cases;
@@ -26,7 +29,7 @@ protected:
        const TestCase &load_test_case(const std::string &);
 
        void verify_output(const std::string &, const std::string &);
-       void verify_error(const std::string &, const std::string &);
+       void verify_diagnostic(const std::string &, const std::string &);
        std::string extract_line(const std::string &, const std::string::const_iterator &);
        virtual void fail(const std::string &) = 0;
 };
@@ -43,6 +46,18 @@ private:
        virtual void fail(const std::string &m) { Test::fail(m); }
 };
 
+class GlslCompilerIdempotence: public Msp::Test::RegisteredTest<GlslCompilerIdempotence>, private GlslCompilerHelper
+{
+public:
+       GlslCompilerIdempotence();
+
+       static const char *get_name() { return "GLSL compiler idempotence"; }
+
+private:
+       void run_test_case(const TestCase *);
+       virtual void fail(const std::string &m) { Test::fail(m); }
+};
+
 using namespace std;
 using namespace Msp;
 
@@ -86,9 +101,12 @@ const GlslCompilerHelper::TestCase &GlslCompilerHelper::load_test_case(const str
                }
 
                pos = line.find("Expected error:");
+               if(pos==string::npos)
+                       pos = line.find("Expected diagnostic:");
                if(pos!=string::npos)
                {
-                       target = &test_case.expected_error;
+                       target = &test_case.expected_diagnostic;
+                       test_case.expect_success = (line[pos+9]!='e');
                        continue;
                }
 
@@ -154,7 +172,7 @@ void GlslCompilerHelper::verify_output(const string &output, const string &expec
        }
 }
 
-void GlslCompilerHelper::verify_error(const string &output, const string &expected)
+void GlslCompilerHelper::verify_diagnostic(const string &output, const string &expected)
 {
        auto i = output.begin();
        auto j = expected.begin();
@@ -180,7 +198,7 @@ void GlslCompilerHelper::verify_error(const string &output, const string &expect
                {
                        string out_line = extract_line(output, i);
                        string expect_line = extract_line(expected, j);
-                       fail(format("Incorrect error line:\n%s\nExpected:\n%s", out_line, expect_line));
+                       fail(format("Incorrect diagnostic line:\n%s\nExpected:\n%s", out_line, expect_line));
                }
        }
 
@@ -190,9 +208,9 @@ void GlslCompilerHelper::verify_error(const string &output, const string &expect
                ++j;
 
        if(i!=output.end())
-               fail(format("Extra error line: %s", extract_line(output, i)));
+               fail(format("Extra diagnostic line: %s", extract_line(output, i)));
        if(j!=expected.end())
-               fail(format("Missing error line: %s", extract_line(expected, j)));
+               fail(format("Missing diagnostic line: %s", extract_line(expected, j)));
 }
 
 string GlslCompilerHelper::extract_line(const string &text, const string::const_iterator &iter)
@@ -216,7 +234,7 @@ GlslCompilerTest::GlslCompilerTest()
 
 void GlslCompilerTest::run_test_case(const TestCase *test_case)
 {
-       GL::SL::Compiler compiler(GL::SL::Features::all());
+       GL::SL::Compiler compiler(GL::SL::Features::latest());
        try
        {
                compiler.set_source(test_case->source, "<test>");
@@ -226,19 +244,21 @@ void GlslCompilerTest::run_test_case(const TestCase *test_case)
        }
        catch(const GL::SL::invalid_shader_source &exc)
        {
-               if(!test_case->expected_error.empty())
+               if(!test_case->expect_success)
                {
                        debug("Errors from compile:");
                        debug(exc.what());
-                       verify_error(exc.what(), test_case->expected_error);
+                       verify_diagnostic(exc.what(), test_case->expected_diagnostic);
                        return;
                }
                throw;
        }
 
-       if(!test_case->expected_error.empty())
+       if(!test_case->expect_success)
                fail("Error expected but none thrown");
 
+       verify_diagnostic(compiler.get_diagnostics(), test_case->expected_diagnostic);
+
        auto stages = compiler.get_stages();
        for(auto s: stages)
        {
@@ -259,3 +279,42 @@ void GlslCompilerTest::run_test_case(const TestCase *test_case)
                if(find(stages, s.first)==stages.end())
                        fail(format("Compiler didn't produce stage %s", GL::SL::Stage::get_stage_name(s.first)));
 }
+
+
+GlslCompilerIdempotence::GlslCompilerIdempotence()
+{
+       load_all_test_cases("glsl");
+       for(const auto &tc: test_cases)
+               if(tc.expect_success)
+                       add(&GlslCompilerIdempotence::run_test_case, &tc, tc.name);
+}
+
+void GlslCompilerIdempotence::run_test_case(const TestCase *test_case)
+{
+       GL::SL::Compiler compiler(GL::SL::Features::latest());
+       compiler.set_source(test_case->source, "<test>");
+       if(test_case->compile_mode==GL::SL::Compiler::PROGRAM)
+               compiler.specialize(test_case->spec_values);
+       compiler.compile(test_case->compile_mode);
+
+       GL::SL::Compiler compiler2(GL::SL::Features::latest());
+       compiler2.set_source(compiler.get_combined_glsl(), "<loopback>");
+       compiler2.compile(test_case->compile_mode);
+
+       auto stages = compiler.get_stages();
+       auto stages2 = compiler2.get_stages();
+       auto i = stages.begin();
+       auto j = stages2.begin();
+       for(; (i!=stages.end() && j!=stages2.end() && *i==*j); ++i, ++j)
+       {
+               string output = compiler.get_stage_glsl(*i);
+               string output2 = compiler2.get_stage_glsl(*j);
+
+               verify_output(output2, output);
+       }
+
+       if(i!=stages.end())
+               fail(format("Second pass didn't produce stage %s", GL::SL::Stage::get_stage_name(*i)));
+       if(j!=stages2.end())
+               fail(format("Second pass produced extra stage %s", GL::SL::Stage::get_stage_name(*j)));
+}