LCOV - code coverage report
Current view: top level - tests - catch_compiler.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 175 246 71.1 %
Date: 2023-07-29 22:00:24 Functions: 11 12 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2023  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/as2js
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software: you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation, either version 3 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License
      17             : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18             : 
      19             : // as2js
      20             : //
      21             : #include    <as2js/compiler.h>
      22             : 
      23             : #include    <as2js/exception.h>
      24             : #include    <as2js/json.h>
      25             : #include    <as2js/message.h>
      26             : #include    <as2js/parser.h>
      27             : 
      28             : 
      29             : // self
      30             : //
      31             : #include    "catch_main.h"
      32             : 
      33             : 
      34             : // snapdev
      35             : //
      36             : #include    <snapdev/string_replace_many.h>
      37             : 
      38             : 
      39             : // C++
      40             : //
      41             : #include    <algorithm>
      42             : #include    <climits>
      43             : #include    <cstring>
      44             : #include    <iomanip>
      45             : 
      46             : 
      47             : // C
      48             : //
      49             : #include    <unistd.h>
      50             : #include    <sys/stat.h>
      51             : 
      52             : 
      53             : // last include
      54             : //
      55             : #include    <snapdev/poison.h>
      56             : 
      57             : 
      58             : 
      59             : namespace
      60             : {
      61             : 
      62             : bool            g_created_files = false;
      63             : 
      64             : 
      65             : 
      66             : 
      67             : class input_retriever
      68             :     : public as2js::input_retriever
      69             : {
      70             : public:
      71           0 :     virtual as2js::base_stream::pointer_t retrieve(std::string const & filename) override
      72             :     {
      73           0 :         if(filename == "")
      74             :         {
      75             :         }
      76             : 
      77           0 :         return as2js::base_stream::pointer_t();
      78             :     }
      79             : 
      80             : };
      81             : 
      82             : 
      83             : std::string     g_current_working_directory;
      84             : 
      85             : 
      86           1 : void init_compiler(as2js::compiler & compiler)
      87             : {
      88             :     // The .rc file cannot be captured by the input retriever
      89             :     // so instead we create a file in the current directory
      90             : 
      91             :     // setup an input retriever which in most cases just returns nullptr
      92             :     //
      93           1 :     compiler.set_input_retriever(std::make_shared<input_retriever>());
      94           1 : }
      95             : 
      96             : 
      97       36866 : void init_rc(bool bad_script = false)
      98             : {
      99             :     // TODO: implement the clean up for this one...
     100             :     //
     101       36866 :     g_created_files = true;
     102             : 
     103             :     // we recreate because in the clean up we may end up deleting that
     104             :     // folder (even though it's already created by the catch_db_init()
     105             :     // function which happens before this call)
     106             :     //
     107       36866 :     if(mkdir("as2js", 0700) != 0)
     108             :     {
     109       36866 :         if(errno != EEXIST)
     110             :         {
     111           0 :             CATCH_REQUIRE(!"could not create directory as2js");
     112             :         }
     113             :         // else -- we already created it, that's fine
     114             :     }
     115             : 
     116             :     // The .rc file cannot be captured by the input retriever
     117             :     // so instead we create a file in the current directory
     118             :     //
     119      110598 :     std::string const safe_cwd(snapdev::string_replace_many(
     120             :                               g_current_working_directory
     121      147464 :                             , { { "'", "\\'" } }));
     122       36866 :     char const * script_path(bad_script ? "no-scripts-here" : "scripts");
     123       36866 :     std::ofstream out("as2js/as2js.rc");
     124             :     out << "// rc test file\n"
     125             :            "{\n"
     126       36866 :            "  'scripts': '" << SNAP_CATCH2_NAMESPACE::g_source_dir() << '/' << script_path << "',\n"
     127             :            "  'db': '" << safe_cwd << "/test.db',\n"
     128             :            "  'temporary_variable_name': '@temp$'\n"
     129       36866 :            "}\n";
     130             : 
     131       36866 :     CATCH_REQUIRE(!!out);
     132       73732 : }
     133             : 
     134             : 
     135           1 : void clean_rc()
     136             : {
     137           1 :     unlink("as2js/as2js.rc");
     138           1 : }
     139             : 
     140             : 
     141             : 
     142             : //
     143             : // JSON data used to test the compiler, most of the work is in this table
     144             : // these are long JSON strings! It is actually generated using the
     145             : // json_to_string tool and the test_as2js_compiler_*.json source files.
     146             : //
     147             : // Note: the top entries are arrays so we can execute programs in the
     148             : //       order we define them...
     149             : //
     150             : char const g_compiler_class[] =
     151             : #include "compiler_data/class.ci"
     152             : ;
     153             : char const g_compiler_expression[] =
     154             : #include "compiler_data/expression.ci"
     155             : ;
     156             : char const g_compiler_enum[] =
     157             : #include "compiler_data/enum.ci"
     158             : ;
     159             : //char const g_compiler_compare[] =
     160             : //#include "compiler_data/compare.ci"
     161             : //;
     162             : //char const g_compiler_conditional[] =
     163             : //#include "compiler_data/conditional.ci"
     164             : //;
     165             : //char const g_compiler_equality[] =
     166             : //#include "compiler_data/equality.ci"
     167             : //;
     168             : //char const g_compiler_logical[] =
     169             : //#include "compiler_data/logical.ci"
     170             : //;
     171             : //char const g_compiler_match[] =
     172             : //#include "compiler_data/match.ci"
     173             : //;
     174             : //char const g_compiler_multiplicative[] =
     175             : //#include "compiler_data/multiplicative.ci"
     176             : //;
     177             : //char const g_compiler_relational[] =
     178             : //#include "compiler_data/relational.ci"
     179             : //;
     180             : //char const g_compiler_statements[] =
     181             : //#include "compiler_data/statements.ci"
     182             : //;
     183             : 
     184             : 
     185             : 
     186             : 
     187             : 
     188             : 
     189             : 
     190             : 
     191             : // This function runs all the tests defined in the
     192             : // string 'data'
     193           3 : void run_tests(char const * input_data, char const *filename)
     194             : {
     195           3 :     if(SNAP_CATCH2_NAMESPACE::g_save_parser_tests)
     196             :     {
     197           0 :         std::ofstream json_file;
     198           0 :         json_file.open(filename);
     199           0 :         CATCH_REQUIRE(json_file.is_open());
     200             :         json_file
     201             :             << "// To properly indent this JSON you may use https://json-indent.appspot.com/\n"
     202             :             << input_data
     203           0 :             << '\n';
     204           0 :     }
     205             : 
     206           3 :     as2js::input_stream<std::stringstream>::pointer_t in(std::make_shared<as2js::input_stream<std::stringstream>>());
     207           3 :     in->get_position().set_filename(filename);
     208           3 :     *in << input_data;
     209           3 :     as2js::json::pointer_t json_data(std::make_shared<as2js::json>());
     210           6 :     as2js::json::json_value::pointer_t json(json_data->parse(in));
     211             : 
     212             :     // verify that the JSON parse() did not fail (internal to test)
     213             :     //
     214           3 :     CATCH_REQUIRE(json != nullptr);
     215           3 :     CATCH_REQUIRE(json->get_type() == as2js::json::json_value::type_t::JSON_TYPE_ARRAY);
     216             : 
     217           6 :     std::string const name_string("name");
     218           6 :     std::string const program_string("program");
     219           6 :     std::string const verbose_string("verbose");
     220           6 :     std::string const slow_string("slow");
     221           6 :     std::string const parser_result_string("parser result");
     222           6 :     std::string const compiler_result_string("compiler result");
     223           6 :     std::string const expected_messages_string("expected messages");
     224             : 
     225           3 :     as2js::json::json_value::array_t const& array(json->get_array());
     226           3 :     std::size_t const max_programs(array.size());
     227          12 :     for(std::size_t idx(0); idx < max_programs; ++idx)
     228             :     {
     229           9 :         as2js::json::json_value::pointer_t prog_obj(array[idx]);
     230           9 :         CATCH_REQUIRE(prog_obj->get_type() == as2js::json::json_value::type_t::JSON_TYPE_OBJECT);
     231           9 :         as2js::json::json_value::object_t const & prog(prog_obj->get_object());
     232             : 
     233           9 :         bool verbose(false);
     234           9 :         as2js::json::json_value::object_t::const_iterator verbose_it(prog.find(verbose_string));
     235           9 :         if(verbose_it != prog.end())
     236             :         {
     237           2 :             verbose = verbose_it->second->get_type() == as2js::json::json_value::type_t::JSON_TYPE_TRUE;
     238             :         }
     239             : 
     240           9 :         bool slow(false);
     241           9 :         as2js::json::json_value::object_t::const_iterator slow_it(prog.find(slow_string));
     242           9 :         if(slow_it != prog.end())
     243             :         {
     244           9 :             slow = slow_it->second->get_type() == as2js::json::json_value::type_t::JSON_TYPE_TRUE;
     245             :         }
     246             : 
     247             :         // got a program, try to compile it with all the possible options
     248           9 :         as2js::json::json_value::pointer_t name(prog.find(name_string)->second);
     249           9 :         std::cout << "  -- working on \"" << name->get_string() << "\" " << (slow ? "" : "...") << std::flush;
     250             : 
     251       36873 :         for(std::size_t opt(0); opt < (1ULL << SNAP_CATCH2_NAMESPACE::g_options_size); ++opt)
     252             :         {
     253       36864 :             if(slow && ((opt + 1) % 250) == 0)
     254             :             {
     255         144 :                 std::cout << "." << std::flush;
     256             :             }
     257             : #define SHOW_OPTIONS 0
     258             : #if SHOW_OPTIONS
     259             : std::cerr << "\n***\n*** OPTIONS: [0x" << std::uppercase << std::hex << opt << std::dec << "]";
     260             : #endif
     261       36864 :             as2js::options::pointer_t options(std::make_shared<as2js::options>());
     262      479232 :             for(std::size_t o(0); o < SNAP_CATCH2_NAMESPACE::g_options_size; ++o)
     263             :             {
     264      442368 :                 if((opt & (1 << o)) != 0)
     265             :                 {
     266      221184 :                     options->set_option(
     267      221184 :                               SNAP_CATCH2_NAMESPACE::g_options[o].f_option
     268      221184 :                             , options->get_option(SNAP_CATCH2_NAMESPACE::g_options[o].f_option)
     269      221184 :                                 | SNAP_CATCH2_NAMESPACE::g_options[o].f_value);
     270             : #if SHOW_OPTIONS
     271             : std::cerr << " " << SNAP_CATCH2_NAMESPACE::g_options[o].f_name << "=" << SNAP_CATCH2_NAMESPACE::g_options[o].f_value;
     272             : #endif
     273             :                 }
     274             :             }
     275             : #if SHOW_OPTIONS
     276             : std::cerr << "\n***\n";
     277             : #endif
     278             : 
     279       36864 :             as2js::json::json_value::pointer_t program_value(prog.find(program_string)->second);
     280       36864 :             std::string program_source(program_value->get_string());
     281             : //std::cerr << "--- prog = [" << program_source << "]\n";
     282       36864 :             as2js::input_stream<std::stringstream>::pointer_t prog_text(std::make_shared<as2js::input_stream<std::stringstream>>());
     283       36864 :             prog_text->get_position().set_filename("test/" + std::string(filename) + ": " + name->get_string());
     284       36864 :             *prog_text << program_source;
     285       36864 :             as2js::parser::pointer_t parser(std::make_shared<as2js::parser>(prog_text, options));
     286             : 
     287       36864 :             init_rc();
     288       36864 :             SNAP_CATCH2_NAMESPACE::test_callback parser_tc(verbose, true);
     289             : 
     290             :             // no errors exepected while parsing (if you want to test errors
     291             :             // in the parser, use the test_as2js_parser.cpp test instead)
     292             :             //
     293       36864 :             as2js::node::pointer_t root(parser->parse());
     294             : //if(name->get_string() == "well defined enum")
     295             : //std::cerr << "--- parser output is:\n" << *root << "\n\n";
     296             : 
     297             :             // verify the parser result, that way we can make sure we are
     298             :             // testing the tree we want to test with the compiler
     299             :             //
     300       36864 :             SNAP_CATCH2_NAMESPACE::verify_result(parser_result_string, prog.find(parser_result_string)->second, root, verbose, false);
     301             : 
     302       36864 :             SNAP_CATCH2_NAMESPACE::test_callback tc(verbose, false);
     303             : 
     304             :             // now the compiler may end up generating messages...
     305             :             //
     306       36864 :             as2js::json::json_value::object_t::const_iterator expected_msg_it(prog.find(expected_messages_string));
     307       36864 :             if(expected_msg_it != prog.end())
     308             :             {
     309             : 
     310             :                 // the expected messages value must be an array
     311             :                 //
     312           0 :                 as2js::json::json_value::array_t const& msg_array(expected_msg_it->second->get_array());
     313           0 :                 std::size_t const max_msgs(msg_array.size());
     314           0 :                 for(std::size_t j(0); j < max_msgs; ++j)
     315             :                 {
     316           0 :                     as2js::json::json_value::pointer_t message_value(msg_array[j]);
     317           0 :                     as2js::json::json_value::object_t const& message(message_value->get_object());
     318             : 
     319           0 :                     bool ignore_message(false);
     320             : 
     321           0 :                     as2js::json::json_value::object_t::const_iterator const message_options_iterator(message.find("options"));
     322           0 :                     if(message_options_iterator != message.end())
     323             :                     {
     324             : //{
     325             : //as2js::json::json_value::object_t::const_iterator line_it(message.find("line #"));
     326             : //if(line_it != message.end())
     327             : //{
     328             : //    int64_t lines(line_it->second->get_integer().get());
     329             : //std::cerr << "_________\nLine #" << lines << "\n";
     330             : //}
     331             : //else
     332             : //std::cerr << "_________\nLine #<undefined>\n";
     333             : //}
     334           0 :                         std::string const message_options(message_options_iterator->second->get_string());
     335           0 :                         for(char const *s(message_options.c_str()), *start(s);; ++s)
     336             :                         {
     337           0 :                             if(*s == ',' || *s == '|' || *s == '\0')
     338             :                             {
     339           0 :                                 std::string const opt_name(start, s - start);
     340           0 :                                 for(std::size_t o(0); o < SNAP_CATCH2_NAMESPACE::g_options_size; ++o)
     341             :                                 {
     342           0 :                                     if(SNAP_CATCH2_NAMESPACE::g_options[o].f_name == opt_name)
     343             :                                     {
     344           0 :                                         ignore_message = (opt & (1 << o)) != 0;
     345             : //std::cerr << "+++ pos option [" << opt_name << "] " << ignore_message << "\n";
     346           0 :                                         goto found_option;
     347             :                                     }
     348           0 :                                     else if(SNAP_CATCH2_NAMESPACE::g_options[o].f_neg_name == opt_name)
     349             :                                     {
     350           0 :                                         ignore_message = (opt & (1 << o)) == 0;
     351             : //std::cerr << "+++ neg option [" << opt_name << "] " << ignore_message << "\n";
     352           0 :                                         goto found_option;
     353             :                                     }
     354             :                                 }
     355           0 :                                 std::cerr << "error: Option \"" << opt_name << "\" not found in our list of valid options\n";
     356           0 :                                 CATCH_REQUIRE("option name from JSON not found in g_options" == nullptr);
     357             : 
     358           0 : found_option:
     359           0 :                                 if(*s == '\0')
     360             :                                 {
     361           0 :                                     break;
     362             :                                 }
     363           0 :                                 if(*s == '|')
     364             :                                 {
     365           0 :                                     if(ignore_message)
     366             :                                     {
     367           0 :                                         break;
     368             :                                     }
     369             :                                 }
     370             :                                 else
     371             :                                 {
     372           0 :                                     if(!ignore_message)
     373             :                                     {
     374           0 :                                         break;
     375             :                                     }
     376             :                                 }
     377             : 
     378             :                                 // skip commas
     379             :                                 do
     380             :                                 {
     381           0 :                                     ++s;
     382             :                                 }
     383           0 :                                 while(*s == ',' || *s == '|');
     384           0 :                                 start = s;
     385           0 :                             }
     386           0 :                         }
     387           0 :                     }
     388             : 
     389           0 :                     if(!ignore_message)
     390             :                     {
     391           0 :                         SNAP_CATCH2_NAMESPACE::test_callback::expected_t expected;
     392           0 :                         expected.f_message_level = static_cast<as2js::message_level_t>(message.find("message level")->second->get_integer().get());
     393           0 :                         expected.f_error_code = SNAP_CATCH2_NAMESPACE::str_to_error_code(message.find("error code")->second->get_string());
     394           0 :                         expected.f_pos.set_filename("unknown-file");
     395           0 :                         as2js::json::json_value::object_t::const_iterator func_it(message.find("function name"));
     396           0 :                         if(func_it == message.end())
     397             :                         {
     398           0 :                             expected.f_pos.set_function("unknown-func");
     399             :                         }
     400             :                         else
     401             :                         {
     402           0 :                             expected.f_pos.set_function(func_it->second->get_string());
     403             :                         }
     404           0 :                         as2js::json::json_value::object_t::const_iterator line_it(message.find("line #"));
     405           0 :                         if(line_it != message.end())
     406             :                         {
     407           0 :                             std::int64_t lines(line_it->second->get_integer().get());
     408           0 :                             for(std::int64_t l(1); l < lines; ++l)
     409             :                             {
     410           0 :                                 expected.f_pos.new_line();
     411             :                             }
     412             :                         }
     413           0 :                         expected.f_message = message.find("message")->second->get_string();
     414           0 :                         tc.f_expected.push_back(expected);
     415           0 :                     }
     416           0 :                 }
     417             :             }
     418             : 
     419             :             // run the compiler
     420             :             //
     421      110592 :             as2js::compiler compiler(options);
     422       36864 :             compiler.compile(root);
     423             : 
     424             : //std::cerr << "  -- compiler root after compiling:\n" << *root << "\n\n";
     425             : 
     426             :             // the result is object which can have children
     427             :             // which are represented by an array of objects
     428             :             //
     429       36864 :             SNAP_CATCH2_NAMESPACE::verify_result(compiler_result_string, prog.find(compiler_result_string)->second, root, verbose, false);
     430             : 
     431       36864 :             tc.got_called();
     432       36864 :         }
     433             : 
     434           9 :         std::cout << " OK\n";
     435           9 :     }
     436             : 
     437           3 :     std::cout << "\n";
     438           6 : }
     439             : 
     440             : 
     441             : }
     442             : // no name namespace
     443             : 
     444             : 
     445             : namespace SNAP_CATCH2_NAMESPACE
     446             : {
     447             : 
     448             : 
     449           1 : int catch_compiler_init()
     450             : {
     451             :     // get the current working directory as we need it in multiple places
     452             :     // that way it's cached and we do not have to duplicate this code over
     453             :     // and over again
     454             :     //
     455           1 :     char * cwd(get_current_dir_name());
     456           1 :     if(cwd == nullptr)
     457             :     {
     458           0 :         std::cerr << "error: could not get the current directory name.\n";
     459           0 :         return 1;
     460             :     }
     461           1 :     g_current_working_directory = cwd;
     462           1 :     free(cwd);
     463             : 
     464           1 :     struct stat st = {};
     465             : 
     466             :     // we do not want a test.db or it could conflict with this test
     467             :     //
     468           1 :     if(stat("test.db", &st) == 0)
     469             :     {
     470             :         std::cerr << "error: file \""
     471             :             << "test.db"
     472           0 :             << "\" already exists; please check it out to make sure you can delete it and try running the test again.\n";
     473           0 :         return 1;
     474             :     }
     475             : 
     476             :     // Now check that we have the scripts directories, we expect
     477             :     // the test to be run from the binary directory and this folder
     478             :     // is found in the source tree... so we have to prepend the
     479             :     // souce dir 
     480             :     //
     481           1 :     std::vector<std::string> script_folders
     482             :     {
     483             :         "scripts",
     484             :         "scripts/extensions",
     485             :         "scripts/native",
     486           9 :     };
     487           4 :     for(auto const & p : script_folders)
     488             :     {
     489           3 :         std::string filename(SNAP_CATCH2_NAMESPACE::g_source_dir());
     490           3 :         filename += '/';
     491           3 :         filename += p;
     492           3 :         if(stat(filename.c_str(), &st) != 0)
     493             :         {
     494             :             std::cerr << "error: file \""
     495             :                 << filename
     496           0 :                 << "\" is missing; please make sure that system scripts are accessible from this test.\n";
     497           0 :             return 1;
     498             :         }
     499           3 :     }
     500             : 
     501           1 :     return 0;
     502           1 : }
     503             : 
     504             : 
     505           2 : void catch_compiler_cleanup()
     506             : {
     507           2 :     if(g_created_files)
     508             :     {
     509             :         // ignore errors on these few calls
     510             :         //
     511           2 :         unlink("test.db");
     512           2 :         unlink("as2js/as2js.rc");
     513           2 :         rmdir("as2js");
     514             :     }
     515           2 : }
     516             : 
     517             : 
     518             : } // namespace SNAP_CATCH2_NAMESPACE
     519             : 
     520             : 
     521             : 
     522             : 
     523             : 
     524           4 : CATCH_TEST_CASE("compiler_invalid_module_files", "[compiler][module][invalid]")
     525             : {
     526           4 :     CATCH_START_SECTION("compiler_invalid_module_files: missing as2js.rc file")
     527             :     {
     528             :         // as2js.rc checked before the options (this is not a really good
     529             :         // test I guess... as the order is only fortuitous)
     530             :         //
     531           1 :         clean_rc();
     532           1 :         as2js::compiler::clean();
     533           2 :         CATCH_REQUIRE_THROWS_MATCHES(
     534             :               std::make_shared<as2js::compiler>(nullptr)
     535             :             , as2js::as2js_exit
     536             :             , Catch::Matchers::ExceptionMessage(
     537             :                       "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
     538             :     }
     539           4 :     CATCH_END_SECTION()
     540             : 
     541           4 :     CATCH_START_SECTION("compiler_invalid_module_files: with option, still missing as2js.rc file")
     542             :     {
     543           1 :         as2js::options::pointer_t options(std::make_shared<as2js::options>());
     544           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     545             :               std::make_shared<as2js::compiler>(options)
     546             :             , as2js::as2js_exit
     547             :             , Catch::Matchers::ExceptionMessage(
     548             :                       "as2js_exception: cannot find the \"as2js.rc\" file; the system default is usually put in \"/etc/as2js/as2js.rc\"."));
     549           1 :     }
     550           4 :     CATCH_END_SECTION()
     551             : 
     552           4 :     CATCH_START_SECTION("compiler_invalid_module_files: invalid path to scripts")
     553             :     {
     554           1 :         init_rc(true);
     555           1 :         as2js::options::pointer_t options(std::make_shared<as2js::options>());
     556           1 :         CATCH_REQUIRE_THROWS_MATCHES(
     557             :               std::make_shared<as2js::compiler>(options)
     558             :             , as2js::as2js_exit
     559             :             , Catch::Matchers::ExceptionMessage(
     560             :                       "as2js_exception: module file \"as2js_init.ajs\" not found in any of the paths \"\"."));
     561           1 :         SNAP_CATCH2_NAMESPACE::catch_compiler_cleanup();
     562           1 :     }
     563           4 :     CATCH_END_SECTION()
     564             : 
     565           4 :     CATCH_START_SECTION("compiler_invalid_module_files: options pointer is required")
     566             :     {
     567           1 :         init_rc();
     568             : 
     569           2 :         CATCH_REQUIRE_THROWS_MATCHES(
     570             :               std::make_shared<as2js::compiler>(nullptr)
     571             :             , as2js::invalid_data
     572             :             , Catch::Matchers::ExceptionMessage(
     573             :                       "as2js_exception: the 'options' pointer cannot be null in the lexer() constructor."));
     574             :     }
     575           4 :     CATCH_END_SECTION()
     576           4 : }
     577             : 
     578             : 
     579           2 : CATCH_TEST_CASE("compiler_invalid_nodes", "[compiler][invalid]")
     580             : {
     581           2 :     CATCH_START_SECTION("compiler_invalid_nodes: empty node does nothing")
     582             :     {
     583           1 :         as2js::node::pointer_t node;
     584           1 :         SNAP_CATCH2_NAMESPACE::test_callback tc(false, false);
     585           1 :         as2js::options::pointer_t options(std::make_shared<as2js::options>());
     586             : 
     587           2 :         as2js::compiler compiler(options);
     588           1 :         init_compiler(compiler);
     589           1 :         CATCH_REQUIRE(compiler.compile(node) == 0);
     590             : 
     591           1 :         tc.got_called();
     592           1 :     }
     593           2 :     CATCH_END_SECTION()
     594             : 
     595           2 :     CATCH_START_SECTION("compiler_invalid_nodes: only ROOT and PROGRAM are valid at the top")
     596             :     {
     597        1163 :         for(int i(-1); i < static_cast<int>(as2js::node_t::NODE_max); ++i)
     598             :         {
     599        1162 :             as2js::node::pointer_t node;
     600             :             try
     601             :             {
     602        1162 :                 node = std::make_shared<as2js::node>(as2js::node_t::NODE_UNKNOWN);
     603             :             }
     604           0 :             catch(as2js::incompatible_type const &)
     605             :             {
     606             :                 // many node types cannot be created
     607             :                 // (we have gaps in our numbers)
     608             :                 //
     609           0 :                 continue;
     610           0 :             }
     611             : 
     612        1162 :             SNAP_CATCH2_NAMESPACE::test_callback tc(false, false);
     613             :             {
     614        1162 :                 SNAP_CATCH2_NAMESPACE::test_callback::expected_t expected;
     615        1162 :                 expected.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     616        1162 :                 expected.f_error_code = as2js::err_code_t::AS_ERR_INTERNAL_ERROR;
     617        1162 :                 expected.f_pos.set_filename("unknown-file");
     618        1162 :                 expected.f_pos.set_function("unknown-func");
     619             :                 //expected.f_pos.new_line(); -- line 1
     620        1162 :                 expected.f_message = "the compiler::compile() function expected a root or a program node to start with.";
     621        1162 :                 tc.f_expected.push_back(expected);
     622        1162 :             }
     623             : 
     624        1162 :             as2js::options::pointer_t options(std::make_shared<as2js::options>());
     625        2324 :             as2js::compiler compiler(options);
     626        1162 :             CATCH_REQUIRE(compiler.compile(node) != 0);
     627        1162 :             CATCH_REQUIRE(node->get_type() == as2js::node_t::NODE_UNKNOWN);
     628        1162 :             CATCH_REQUIRE(node->get_children_size() == 0);
     629        1162 :         }
     630             :     }
     631           2 :     CATCH_END_SECTION()
     632           2 : }
     633             : 
     634             : 
     635           1 : CATCH_TEST_CASE("compiler_class", "[compiler][class]")
     636             : {
     637           1 :     CATCH_START_SECTION("compiler_class: verify class functionality")
     638             :     {
     639           1 :         run_tests(g_compiler_class, "compiler/class.json");
     640             :     }
     641           1 :     CATCH_END_SECTION()
     642           1 : }
     643             : 
     644             : 
     645           1 : CATCH_TEST_CASE("compiler_enum", "[compiler][enum]")
     646             : {
     647           1 :     CATCH_START_SECTION("compiler_enum: verify enumerations")
     648             :     {
     649           1 :         run_tests(g_compiler_enum, "compiler/enum.json");
     650             :     }
     651           1 :     CATCH_END_SECTION()
     652           1 : }
     653             : 
     654             : 
     655           1 : CATCH_TEST_CASE("compiler_expression", "[compiler][expression]")
     656             : {
     657           1 :     CATCH_START_SECTION("compiler_expression: verify expressions")
     658             :     {
     659           1 :         run_tests(g_compiler_expression, "compiler/expression.json");
     660             :     }
     661           1 :     CATCH_END_SECTION()
     662           1 : }
     663             : 
     664             : 
     665             : 
     666             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14