LCOV - code coverage report
Current view: top level - tests - test_as2js_compiler.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 340 550 61.8 %
Date: 2014-11-22 Functions: 23 32 71.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* test_as2js_compiler.cpp -- written by Alexis WILKE for Made to Order Software Corp. (c) 2005-2014 */
       2             : 
       3             : /*
       4             : 
       5             : Copyright (c) 2005-2014 Made to Order Software Corp.
       6             : 
       7             : http://snapwebsites.org/project/as2js
       8             : 
       9             : Permission is hereby granted, free of charge, to any
      10             : person obtaining a copy of this software and
      11             : associated documentation files (the "Software"), to
      12             : deal in the Software without restriction, including
      13             : without limitation the rights to use, copy, modify,
      14             : merge, publish, distribute, sublicense, and/or sell
      15             : copies of the Software, and to permit persons to whom
      16             : the Software is furnished to do so, subject to the
      17             : following conditions:
      18             : 
      19             : The above copyright notice and this permission notice
      20             : shall be included in all copies or substantial
      21             : portions of the Software.
      22             : 
      23             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
      24             : ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
      25             : LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
      26             : FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
      27             : EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      28             : LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      29             : WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      30             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      31             : SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      32             : SOFTWARE.
      33             : 
      34             : */
      35             : 
      36             : #include    "test_as2js_compiler.h"
      37             : #include    "test_as2js_main.h"
      38             : 
      39             : #include    "as2js/compiler.h"
      40             : #include    "as2js/parser.h"
      41             : #include    "as2js/exceptions.h"
      42             : #include    "as2js/message.h"
      43             : #include    "as2js/json.h"
      44             : 
      45             : #include    <controlled_vars/controlled_vars_limited_auto_enum_init.h>
      46             : 
      47             : #include    <unistd.h>
      48             : #include    <sys/stat.h>
      49             : 
      50             : #include    <cstring>
      51             : #include    <algorithm>
      52             : #include    <iomanip>
      53             : 
      54             : #include    <cppunit/config/SourcePrefix.h>
      55           4 : CPPUNIT_TEST_SUITE_REGISTRATION( As2JsCompilerUnitTests );
      56             : 
      57             : namespace
      58             : {
      59             : 
      60             : bool            g_created_files = false;
      61             : 
      62             : struct err_to_string_t
      63             : {
      64             :     as2js::err_code_t       f_code;
      65             :     char const *            f_name;
      66             :     int                     f_line;
      67             : };
      68             : 
      69             : #define    TO_STR_sub(s)       #s
      70             : #define    ERROR_NAME(err)     { as2js::err_code_t::AS_ERR_##err, TO_STR_sub(err), __LINE__ }
      71             : 
      72             : err_to_string_t const g_error_table[] =
      73             : {
      74             :     ERROR_NAME(NONE),
      75             :     ERROR_NAME(ABSTRACT),
      76             :     ERROR_NAME(BAD_NUMERIC_TYPE),
      77             :     ERROR_NAME(BAD_PRAGMA),
      78             :     ERROR_NAME(CANNOT_COMPILE),
      79             :     ERROR_NAME(CANNOT_MATCH),
      80             :     ERROR_NAME(CANNOT_OVERLOAD),
      81             :     ERROR_NAME(CANNOT_OVERWRITE_CONST),
      82             :     ERROR_NAME(CASE_LABEL),
      83             :     ERROR_NAME(COLON_EXPECTED),
      84             :     ERROR_NAME(COMMA_EXPECTED),
      85             :     ERROR_NAME(CURVLY_BRACKETS_EXPECTED),
      86             :     ERROR_NAME(DEFAULT_LABEL),
      87             :     ERROR_NAME(DIVIDE_BY_ZERO),
      88             :     ERROR_NAME(DUPLICATES),
      89             :     ERROR_NAME(DYNAMIC),
      90             :     ERROR_NAME(EXPRESSION_EXPECTED),
      91             :     ERROR_NAME(FINAL),
      92             :     ERROR_NAME(IMPROPER_STATEMENT),
      93             :     ERROR_NAME(INACCESSIBLE_STATEMENT),
      94             :     ERROR_NAME(INCOMPATIBLE),
      95             :     ERROR_NAME(INCOMPATIBLE_PRAGMA_ARGUMENT),
      96             :     ERROR_NAME(INSTALLATION),
      97             :     ERROR_NAME(INSTANCE_EXPECTED),
      98             :     ERROR_NAME(INTERNAL_ERROR),
      99             :     ERROR_NAME(NATIVE),
     100             :     ERROR_NAME(INVALID_ARRAY_FUNCTION),
     101             :     ERROR_NAME(INVALID_ATTRIBUTES),
     102             :     ERROR_NAME(INVALID_CATCH),
     103             :     ERROR_NAME(INVALID_CLASS),
     104             :     ERROR_NAME(INVALID_CONDITIONAL),
     105             :     ERROR_NAME(INVALID_DEFINITION),
     106             :     ERROR_NAME(INVALID_DO),
     107             :     ERROR_NAME(INVALID_ENUM),
     108             :     ERROR_NAME(INVALID_EXPRESSION),
     109             :     ERROR_NAME(INVALID_FIELD),
     110             :     ERROR_NAME(INVALID_FIELD_NAME),
     111             :     ERROR_NAME(INVALID_FRAME),
     112             :     ERROR_NAME(INVALID_FUNCTION),
     113             :     ERROR_NAME(INVALID_GOTO),
     114             :     ERROR_NAME(INVALID_IMPORT),
     115             :     ERROR_NAME(INVALID_INPUT_STREAM),
     116             :     ERROR_NAME(INVALID_KEYWORD),
     117             :     ERROR_NAME(INVALID_LABEL),
     118             :     ERROR_NAME(INVALID_NAMESPACE),
     119             :     ERROR_NAME(INVALID_NODE),
     120             :     ERROR_NAME(INVALID_NUMBER),
     121             :     ERROR_NAME(INVALID_OPERATOR),
     122             :     ERROR_NAME(INVALID_PACKAGE_NAME),
     123             :     ERROR_NAME(INVALID_PARAMETERS),
     124             :     ERROR_NAME(INVALID_REST),
     125             :     ERROR_NAME(INVALID_RETURN_TYPE),
     126             :     ERROR_NAME(INVALID_SCOPE),
     127             :     ERROR_NAME(INVALID_TRY),
     128             :     ERROR_NAME(INVALID_TYPE),
     129             :     ERROR_NAME(INVALID_UNICODE_ESCAPE_SEQUENCE),
     130             :     ERROR_NAME(INVALID_VARIABLE),
     131             :     ERROR_NAME(IO_ERROR),
     132             :     ERROR_NAME(LABEL_NOT_FOUND),
     133             :     ERROR_NAME(LOOPING_REFERENCE),
     134             :     ERROR_NAME(MISMATCH_FUNC_VAR),
     135             :     ERROR_NAME(MISSSING_VARIABLE_NAME),
     136             :     ERROR_NAME(NEED_CONST),
     137             :     ERROR_NAME(NOT_ALLOWED),
     138             :     ERROR_NAME(NOT_ALLOWED_IN_STRICT_MODE),
     139             :     ERROR_NAME(NOT_FOUND),
     140             :     ERROR_NAME(NOT_SUPPORTED),
     141             :     ERROR_NAME(OBJECT_MEMBER_DEFINED_TWICE),
     142             :     ERROR_NAME(PARENTHESIS_EXPECTED),
     143             :     ERROR_NAME(PRAGMA_FAILED),
     144             :     ERROR_NAME(SEMICOLON_EXPECTED),
     145             :     ERROR_NAME(SQUARE_BRACKETS_EXPECTED),
     146             :     ERROR_NAME(STRING_EXPECTED),
     147             :     ERROR_NAME(STATIC),
     148             :     ERROR_NAME(TYPE_NOT_LINKED),
     149             :     ERROR_NAME(UNKNOWN_ESCAPE_SEQUENCE),
     150             :     ERROR_NAME(UNKNOWN_OPERATOR),
     151             :     ERROR_NAME(UNTERMINATED_STRING),
     152             :     ERROR_NAME(UNEXPECTED_EOF),
     153             :     ERROR_NAME(UNEXPECTED_PUNCTUATION),
     154             :     ERROR_NAME(UNEXPECTED_TOKEN),
     155             :     ERROR_NAME(UNEXPECTED_DATABASE),
     156             :     ERROR_NAME(UNEXPECTED_RC)
     157             : };
     158             : size_t const g_error_table_size = sizeof(g_error_table) / sizeof(g_error_table[0]);
     159             : 
     160             : 
     161           0 : as2js::err_code_t str_to_error_code(as2js::String const& error_name)
     162             : {
     163           0 :     for(size_t idx(0); idx < g_error_table_size; ++idx)
     164             :     {
     165           0 :         if(error_name == g_error_table[idx].f_name)
     166             :         {
     167           0 :             return g_error_table[idx].f_code;
     168             :         }
     169             :     }
     170           0 :     std::cerr << "Error name \"" << error_name << "\" not found.\n";
     171           0 :     CPPUNIT_ASSERT(!"error name not found, test_as2js_compiler.cpp bug");
     172           0 :     return as2js::err_code_t::AS_ERR_NONE;
     173             : }
     174             : 
     175             : 
     176           0 : char const *error_code_to_str(as2js::err_code_t const& error_code)
     177             : {
     178           0 :     for(size_t idx(0); idx < g_error_table_size; ++idx)
     179             :     {
     180           0 :         if(error_code == g_error_table[idx].f_code)
     181             :         {
     182           0 :             return g_error_table[idx].f_name;
     183             :         }
     184             :     }
     185           0 :     std::cerr << "Error code \"" << static_cast<int>(error_code) << "\" not found.\n";
     186           0 :     CPPUNIT_ASSERT(!"error code not found, test_as2js_compiler.cpp bug");
     187           0 :     return "unknown";
     188             : }
     189             : 
     190             : 
     191             : 
     192             : class test_callback : public as2js::MessageCallback
     193             : {
     194             : public:
     195        9339 :     test_callback(bool verbose)
     196        9339 :         : f_verbose(verbose)
     197             :     {
     198        9339 :         as2js::Message::set_message_callback(this);
     199        9339 :         g_warning_count = as2js::Message::warning_count();
     200        9339 :         g_error_count = as2js::Message::error_count();
     201        9339 :     }
     202             : 
     203        9339 :     ~test_callback()
     204       18678 :     {
     205             :         // make sure the pointer gets reset!
     206        9339 :         as2js::Message::set_message_callback(nullptr);
     207        9339 :     }
     208             : 
     209             :     // implementation of the output
     210        1146 :     virtual void output(as2js::message_level_t message_level, as2js::err_code_t error_code, as2js::Position const& pos, std::string const& message)
     211             :     {
     212             :         // skip trace messages which happen all the time because of the
     213             :         // lexer debug option
     214        1146 :         if(message_level == as2js::message_level_t::MESSAGE_LEVEL_TRACE)
     215             :         {
     216        1146 :             return;
     217             :         }
     218             : 
     219        1146 :         if(f_expected.empty())
     220             :         {
     221           0 :             std::cerr << "\n*** STILL NECESSARY ***\n";
     222           0 :             std::cerr << "filename = " << pos.get_filename() << "\n";
     223           0 :             std::cerr << "msg = " << message << "\n";
     224           0 :             std::cerr << "page = " << pos.get_page() << "\n";
     225           0 :             std::cerr << "line = " << pos.get_line() << "\n";
     226           0 :             std::cerr << "error_code = " << static_cast<int>(error_code) << " (" << error_code_to_str(error_code) << ")\n";
     227             :         }
     228             : 
     229        1146 :         CPPUNIT_ASSERT(!f_expected.empty());
     230             : 
     231        1146 :         if(f_verbose)
     232             :         {
     233           0 :             std::cerr << "filename = " << pos.get_filename() << " (node) / " << f_expected[0].f_pos.get_filename() << " (JSON)\n";
     234           0 :             std::cerr << "msg = " << message << " / " << f_expected[0].f_message << "\n";
     235           0 :             std::cerr << "page = " << pos.get_page() << " / " << f_expected[0].f_pos.get_page() << "\n";
     236           0 :             std::cerr << "line = " << pos.get_line() << " / " << f_expected[0].f_pos.get_line() << "\n";
     237           0 :             std::cerr << "page line = " << pos.get_page_line() << " / " << f_expected[0].f_pos.get_page_line() << "\n";
     238           0 :             std::cerr << "error_code = " << static_cast<int>(error_code) << " (" << error_code_to_str(error_code) << ") / " << static_cast<int>(f_expected[0].f_error_code) << " (" << error_code_to_str(f_expected[0].f_error_code) << ")\n";
     239             :         }
     240             : 
     241        1146 :         CPPUNIT_ASSERT(f_expected[0].f_call);
     242        1146 :         CPPUNIT_ASSERT(message_level == f_expected[0].f_message_level);
     243        1146 :         CPPUNIT_ASSERT(error_code == f_expected[0].f_error_code);
     244        1146 :         CPPUNIT_ASSERT(pos.get_filename() == f_expected[0].f_pos.get_filename());
     245        1146 :         CPPUNIT_ASSERT(pos.get_function() == f_expected[0].f_pos.get_function());
     246        1146 :         CPPUNIT_ASSERT(pos.get_page() == f_expected[0].f_pos.get_page());
     247        1146 :         CPPUNIT_ASSERT(pos.get_page_line() == f_expected[0].f_pos.get_page_line());
     248        1146 :         CPPUNIT_ASSERT(pos.get_paragraph() == f_expected[0].f_pos.get_paragraph());
     249        1146 :         CPPUNIT_ASSERT(pos.get_line() == f_expected[0].f_pos.get_line());
     250        1146 :         CPPUNIT_ASSERT(message == f_expected[0].f_message.to_utf8());
     251             : 
     252        1146 :         if(message_level == as2js::message_level_t::MESSAGE_LEVEL_WARNING)
     253             :         {
     254           0 :             ++g_warning_count;
     255           0 :             CPPUNIT_ASSERT(g_warning_count == as2js::Message::warning_count());
     256             :         }
     257             : 
     258        1146 :         if(message_level == as2js::message_level_t::MESSAGE_LEVEL_FATAL
     259        1146 :         || message_level == as2js::message_level_t::MESSAGE_LEVEL_ERROR)
     260             :         {
     261        1146 :             ++g_error_count;
     262             : //std::cerr << "error: " << g_error_count << " / " << as2js::Message::error_count() << "\n";
     263        1146 :             CPPUNIT_ASSERT(g_error_count == as2js::Message::error_count());
     264             :         }
     265             : 
     266        1146 :         f_expected.erase(f_expected.begin());
     267             :     }
     268             : 
     269        8192 :     void got_called()
     270             :     {
     271        8192 :         if(!f_expected.empty())
     272             :         {
     273           0 :             std::cerr << "\n*** STILL " << f_expected.size() << " EXPECTED ***\n";
     274           0 :             std::cerr << "filename = " << f_expected[0].f_pos.get_filename() << "\n";
     275           0 :             std::cerr << "msg = " << f_expected[0].f_message << "\n";
     276           0 :             std::cerr << "page = " << f_expected[0].f_pos.get_page() << "\n";
     277           0 :             std::cerr << "error_code = " << static_cast<int>(f_expected[0].f_error_code) << "\n";
     278             :         }
     279        8192 :         CPPUNIT_ASSERT(f_expected.empty());
     280        8192 :     }
     281             : 
     282        4584 :     struct expected_t
     283             :     {
     284             :         controlled_vars::tlbool_t   f_call;
     285             :         as2js::message_level_t      f_message_level;
     286             :         as2js::err_code_t           f_error_code;
     287             :         as2js::Position             f_pos;
     288             :         as2js::String               f_message; // UTF-8 string
     289             :     };
     290             : 
     291             :     std::vector<expected_t>     f_expected;
     292             :     controlled_vars::fbool_t    f_verbose;
     293             : 
     294             :     static controlled_vars::zint32_t   g_warning_count;
     295             :     static controlled_vars::zint32_t   g_error_count;
     296             : };
     297             : 
     298           4 : controlled_vars::zint32_t   test_callback::g_warning_count;
     299           4 : controlled_vars::zint32_t   test_callback::g_error_count;
     300             : 
     301           4 : controlled_vars::zint32_t   g_empty_home_too_late;
     302             : 
     303             : 
     304             : //
     305             : // we have two special pragmas that accept 0, 1, 2, or 3
     306             : // namely, those are:
     307             : //
     308             : //  . OPTION_EXTENDED_STATEMENTS -- force '{' ... '}' in
     309             : //    blocks for: if, while, do, for, with...
     310             : //
     311             : //  . OPTION_EXTENDED_OPERATORS -- force ':=' instead of '='
     312             : //
     313             : // for this reason we support and f_value which is viewed
     314             : // as a set of flags
     315             : //
     316             : struct named_options
     317             : {
     318             :     as2js::Options::option_t    f_option;
     319             :     char const *                f_name;
     320             :     char const *                f_neg_name;
     321             :     int                         f_value;
     322             : };
     323             : named_options const g_options[] =
     324             : {
     325             :     {
     326             :         as2js::Options::option_t::OPTION_ALLOW_WITH,
     327             :         "allow_with",
     328             :         "no_allow_with",
     329             :         1
     330             :     },
     331             :     {
     332             :         as2js::Options::option_t::OPTION_BINARY,
     333             :         "binary",
     334             :         "no_binary",
     335             :         1
     336             :     },
     337             :     {
     338             :         as2js::Options::option_t::OPTION_COVERAGE,
     339             :         "coverage",
     340             :         "no_coverage",
     341             :         1
     342             :     },
     343             :     {
     344             :         as2js::Options::option_t::OPTION_DEBUG,
     345             :         "debug",
     346             :         "no_debug",
     347             :         1
     348             :     },
     349             :     {
     350             :         as2js::Options::option_t::OPTION_EXTENDED_ESCAPE_SEQUENCES,
     351             :         "extended_escape_sequences",
     352             :         "no_extended_escape_sequences",
     353             :         1
     354             :     },
     355             :     {
     356             :         as2js::Options::option_t::OPTION_EXTENDED_OPERATORS,
     357             :         "extended_operators",
     358             :         "no_extended_operators",
     359             :         1
     360             :     },
     361             :     {
     362             :         as2js::Options::option_t::OPTION_EXTENDED_OPERATORS,
     363             :         "extended_operators_safe",
     364             :         "no_extended_operators_safe",
     365             :         2
     366             :     },
     367             :     {
     368             :         as2js::Options::option_t::OPTION_EXTENDED_STATEMENTS,
     369             :         "extended_statements",
     370             :         "no_extended_statements",
     371             :         1
     372             :     },
     373             :     {
     374             :         as2js::Options::option_t::OPTION_EXTENDED_STATEMENTS,
     375             :         "extended_statements_safe",
     376             :         "no_extended_statements_safe",
     377             :         2
     378             :     },
     379             :     //{ -- this one does not make sense here
     380             :     //    as2js::Options::option_t::OPTION_JSON,
     381             :     //    "json",
     382             :     //    "no_json"
     383             :     //},
     384             :     {
     385             :         as2js::Options::option_t::OPTION_OCTAL,
     386             :         "octal",
     387             :         "no_octal",
     388             :         1
     389             :     },
     390             :     {
     391             :         as2js::Options::option_t::OPTION_STRICT,
     392             :         "strict",
     393             :         "no_strict",
     394             :         1
     395             :     },
     396             :     {
     397             :         as2js::Options::option_t::OPTION_TRACE,
     398             :         "trace",
     399             :         "no_trace",
     400             :         1
     401             :     },
     402             :     {
     403             :         as2js::Options::option_t::OPTION_UNSAFE_MATH,
     404             :         "unsafe_math",
     405             :         "no_unsafe_math",
     406             :         1
     407             :     }
     408             : };
     409             : size_t const g_options_size(sizeof(g_options) / sizeof(g_options[0]));
     410             : 
     411             : 
     412             : struct flg_to_string_t
     413             : {
     414             :     as2js::Node::flag_t     f_flag;
     415             :     char const *            f_name;
     416             :     int                     f_line;
     417             : };
     418             : 
     419             : #define    FLAG_NAME(flg)     { as2js::Node::flag_t::NODE_##flg, TO_STR_sub(flg), __LINE__ }
     420             : 
     421             : flg_to_string_t const g_flag_table[] =
     422             : {
     423             :     FLAG_NAME(CATCH_FLAG_TYPED),
     424             :     FLAG_NAME(DIRECTIVE_LIST_FLAG_NEW_VARIABLES),
     425             :     FLAG_NAME(ENUM_FLAG_CLASS),
     426             :     FLAG_NAME(FOR_FLAG_CONST),
     427             :     FLAG_NAME(FOR_FLAG_FOREACH),
     428             :     FLAG_NAME(FOR_FLAG_IN),
     429             :     FLAG_NAME(FUNCTION_FLAG_GETTER),
     430             :     FLAG_NAME(FUNCTION_FLAG_SETTER),
     431             :     FLAG_NAME(FUNCTION_FLAG_OUT),
     432             :     FLAG_NAME(FUNCTION_FLAG_VOID),
     433             :     FLAG_NAME(FUNCTION_FLAG_NEVER),
     434             :     FLAG_NAME(FUNCTION_FLAG_NOPARAMS),
     435             :     FLAG_NAME(FUNCTION_FLAG_OPERATOR),
     436             :     FLAG_NAME(IDENTIFIER_FLAG_WITH),
     437             :     FLAG_NAME(IDENTIFIER_FLAG_TYPED),
     438             :     FLAG_NAME(IMPORT_FLAG_IMPLEMENTS),
     439             :     FLAG_NAME(PACKAGE_FLAG_FOUND_LABELS),
     440             :     FLAG_NAME(PACKAGE_FLAG_REFERENCED),
     441             :     FLAG_NAME(PARAM_FLAG_CONST),
     442             :     FLAG_NAME(PARAM_FLAG_IN),
     443             :     FLAG_NAME(PARAM_FLAG_OUT),
     444             :     FLAG_NAME(PARAM_FLAG_NAMED),
     445             :     FLAG_NAME(PARAM_FLAG_REST),
     446             :     FLAG_NAME(PARAM_FLAG_UNCHECKED),
     447             :     FLAG_NAME(PARAM_FLAG_UNPROTOTYPED),
     448             :     FLAG_NAME(PARAM_FLAG_REFERENCED),
     449             :     FLAG_NAME(PARAM_FLAG_PARAMREF),
     450             :     FLAG_NAME(PARAM_FLAG_CATCH),
     451             :     FLAG_NAME(PARAM_MATCH_FLAG_UNPROTOTYPED),
     452             :     FLAG_NAME(SWITCH_FLAG_DEFAULT),
     453             :     FLAG_NAME(TYPE_FLAG_MODULO),
     454             :     FLAG_NAME(VARIABLE_FLAG_CONST),
     455             :     FLAG_NAME(VARIABLE_FLAG_LOCAL),
     456             :     FLAG_NAME(VARIABLE_FLAG_MEMBER),
     457             :     FLAG_NAME(VARIABLE_FLAG_ATTRIBUTES),
     458             :     FLAG_NAME(VARIABLE_FLAG_ENUM),
     459             :     FLAG_NAME(VARIABLE_FLAG_COMPILED),
     460             :     FLAG_NAME(VARIABLE_FLAG_INUSE),
     461             :     FLAG_NAME(VARIABLE_FLAG_ATTRS),
     462             :     FLAG_NAME(VARIABLE_FLAG_DEFINED),
     463             :     FLAG_NAME(VARIABLE_FLAG_DEFINING),
     464             :     FLAG_NAME(VARIABLE_FLAG_TOADD)
     465             : };
     466             : size_t const g_flag_table_size = sizeof(g_flag_table) / sizeof(g_flag_table[0]);
     467             : 
     468             : 
     469           0 : as2js::Node::flag_t str_to_flag_code(as2js::String const& flag_name)
     470             : {
     471           0 :     for(size_t idx(0); idx < g_flag_table_size; ++idx)
     472             :     {
     473           0 :         if(flag_name == g_flag_table[idx].f_name)
     474             :         {
     475           0 :             return g_flag_table[idx].f_flag;
     476             :         }
     477             :     }
     478           0 :     CPPUNIT_ASSERT(!"flag code not found, test_as2js_compiler.cpp bug");
     479           0 :     return as2js::Node::flag_t::NODE_FLAG_max;
     480             : }
     481             : 
     482             : 
     483           0 : as2js::String flag_to_str(as2js::Node::flag_t& flg)
     484             : {
     485           0 :     for(size_t idx(0); idx < g_flag_table_size; ++idx)
     486             :     {
     487           0 :         if(flg == g_flag_table[idx].f_flag)
     488             :         {
     489           0 :             return g_flag_table[idx].f_name;
     490             :         }
     491             :     }
     492           0 :     CPPUNIT_ASSERT(!"flag code not found, test_as2js_compiler.cpp bug");
     493           0 :     return "";
     494             : }
     495             : 
     496             : 
     497             : 
     498             : 
     499       65536 : void verify_flags(as2js::Node::pointer_t node, as2js::String const& flags_set, bool verbose)
     500             : {
     501             :     // list of flags that have to be set
     502       65536 :     std::vector<as2js::Node::flag_t> flgs;
     503       65536 :     as2js::as_char_t const *f(flags_set.c_str());
     504       65536 :     as2js::as_char_t const *s(f);
     505             :     for(;;)
     506             :     {
     507       65536 :         if(*f == ',' || *f == '\0')
     508             :         {
     509       65536 :             if(s == f)
     510             :             {
     511      131072 :                 break;
     512             :             }
     513           0 :             as2js::String name(s, f - s);
     514             : //std::cerr << "Checking " << name << " -> " << static_cast<int>(str_to_flag_code(name)) << "\n";
     515           0 :             flgs.push_back(str_to_flag_code(name));
     516           0 :             if(*f == '\0')
     517             :             {
     518           0 :                 break;
     519             :             }
     520           0 :             do // skip commas
     521             :             {
     522           0 :                 ++f;
     523             :             }
     524           0 :             while(*f == ',');
     525           0 :             s = f;
     526             :         }
     527             :         else
     528             :         {
     529           0 :             ++f;
     530             :         }
     531           0 :     }
     532             : 
     533             :     // list of flags that must be checked
     534      131072 :     std::vector<as2js::Node::flag_t> flgs_to_check;
     535       65536 :     switch(node->get_type())
     536             :     {
     537             :     case as2js::Node::node_t::NODE_CATCH:
     538           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_CATCH_FLAG_TYPED);
     539           0 :         break;
     540             : 
     541             :     case as2js::Node::node_t::NODE_DIRECTIVE_LIST:
     542       16384 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_DIRECTIVE_LIST_FLAG_NEW_VARIABLES);
     543       16384 :         break;
     544             : 
     545             :     case as2js::Node::node_t::NODE_ENUM:
     546           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_ENUM_FLAG_CLASS);
     547           0 :         break;
     548             : 
     549             :     case as2js::Node::node_t::NODE_FOR:
     550           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FOR_FLAG_CONST);
     551           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FOR_FLAG_FOREACH);
     552           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FOR_FLAG_IN);
     553           0 :         break;
     554             : 
     555             :     case as2js::Node::node_t::NODE_FUNCTION:
     556           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_GETTER);
     557           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_NEVER);
     558           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_NOPARAMS);
     559           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_OPERATOR);
     560           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_OUT);
     561           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_SETTER);
     562           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_FUNCTION_FLAG_VOID);
     563           0 :         break;
     564             : 
     565             :     case as2js::Node::node_t::NODE_IDENTIFIER:
     566             :     case as2js::Node::node_t::NODE_VIDENTIFIER:
     567             :     case as2js::Node::node_t::NODE_STRING:
     568           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_IDENTIFIER_FLAG_WITH);
     569           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_IDENTIFIER_FLAG_TYPED);
     570           0 :         break;
     571             : 
     572             :     case as2js::Node::node_t::NODE_IMPORT:
     573           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_IMPORT_FLAG_IMPLEMENTS);
     574           0 :         break;
     575             : 
     576             :     case as2js::Node::node_t::NODE_PACKAGE:
     577           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PACKAGE_FLAG_FOUND_LABELS);
     578           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PACKAGE_FLAG_REFERENCED);
     579           0 :         break;
     580             : 
     581             :     case as2js::Node::node_t::NODE_PARAM_MATCH:
     582           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_MATCH_FLAG_UNPROTOTYPED);
     583           0 :         break;
     584             : 
     585             :     case as2js::Node::node_t::NODE_PARAM:
     586           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_CATCH);
     587           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_CONST);
     588           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_IN);
     589           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_OUT);
     590           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_NAMED);
     591           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_PARAMREF);
     592           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_REFERENCED);
     593           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_REST);
     594           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_UNCHECKED);
     595           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_PARAM_FLAG_UNPROTOTYPED);
     596           0 :         break;
     597             : 
     598             :     case as2js::Node::node_t::NODE_SWITCH:
     599           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_SWITCH_FLAG_DEFAULT);
     600           0 :         break;
     601             : 
     602             :     case as2js::Node::node_t::NODE_TYPE:
     603           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_TYPE_FLAG_MODULO);
     604           0 :         break;
     605             : 
     606             :     case as2js::Node::node_t::NODE_VARIABLE:
     607             :     case as2js::Node::node_t::NODE_VAR_ATTRIBUTES:
     608           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_CONST);
     609           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_LOCAL);
     610           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_MEMBER);
     611           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_ATTRIBUTES);
     612           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_ENUM);
     613           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_COMPILED);
     614           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_INUSE);
     615           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_ATTRS);
     616           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_DEFINED);
     617           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_DEFINING);
     618           0 :         flgs_to_check.push_back(as2js::Node::flag_t::NODE_VARIABLE_FLAG_TOADD);
     619           0 :         break;
     620             : 
     621             :     default:
     622             :         // no flags supported
     623       49152 :         break;
     624             : 
     625             :     }
     626             : 
     627       65536 :     CPPUNIT_ASSERT(flgs.size() <= flgs_to_check.size());
     628             : 
     629       81920 :     for(size_t idx(0); idx < flgs_to_check.size(); ++idx)
     630             :     {
     631       16384 :         as2js::Node::flag_t flg(flgs_to_check[idx]);
     632       16384 :         std::vector<as2js::Node::flag_t>::iterator it(std::find(flgs.begin(), flgs.end(), flg));
     633       16384 :         if(it == flgs.end())
     634             :         {
     635             :             // expected to be unset
     636       16384 :             if(verbose && node->get_flag(flg))
     637             :             {
     638           0 :                 std::cerr << "*** Comparing flags " << flag_to_str(flg) << " (should not be set)\n";
     639             :             }
     640       16384 :             CPPUNIT_ASSERT(!node->get_flag(flg));
     641             :         }
     642             :         else
     643             :         {
     644             :             // expected to be set
     645           0 :             flgs.erase(it);
     646           0 :             if(verbose && !node->get_flag(flg))
     647             :             {
     648           0 :                 std::cerr << "*** Comparing flags " << flag_to_str(flg) << " (it should be set in this case)\n";
     649             :             }
     650           0 :             CPPUNIT_ASSERT(node->get_flag(flg));
     651             :         }
     652             :     }
     653             : 
     654      131072 :     CPPUNIT_ASSERT(flgs.empty());
     655       65536 : }
     656             : 
     657             : 
     658             : 
     659             : 
     660             : struct attr_to_string_t
     661             : {
     662             :     as2js::Node::attribute_t    f_attribute;
     663             :     char const *                f_name;
     664             :     int                         f_line;
     665             : };
     666             : 
     667             : #define    ATTRIBUTE_NAME(attr)      { as2js::Node::attribute_t::NODE_ATTR_##attr, TO_STR_sub(attr), __LINE__ }
     668             : 
     669             : attr_to_string_t const g_attribute_table[] =
     670             : {
     671             :     ATTRIBUTE_NAME(PUBLIC),
     672             :     ATTRIBUTE_NAME(PRIVATE),
     673             :     ATTRIBUTE_NAME(PROTECTED),
     674             :     ATTRIBUTE_NAME(INTERNAL),
     675             :     ATTRIBUTE_NAME(TRANSIENT),
     676             :     ATTRIBUTE_NAME(VOLATILE),
     677             :     ATTRIBUTE_NAME(STATIC),
     678             :     ATTRIBUTE_NAME(ABSTRACT),
     679             :     ATTRIBUTE_NAME(VIRTUAL),
     680             :     ATTRIBUTE_NAME(ARRAY),
     681             :     ATTRIBUTE_NAME(REQUIRE_ELSE),
     682             :     ATTRIBUTE_NAME(ENSURE_THEN),
     683             :     ATTRIBUTE_NAME(NATIVE),
     684             :     ATTRIBUTE_NAME(DEPRECATED),
     685             :     ATTRIBUTE_NAME(UNSAFE),
     686             :     ATTRIBUTE_NAME(CONSTRUCTOR),
     687             :     ATTRIBUTE_NAME(FINAL),
     688             :     ATTRIBUTE_NAME(ENUMERABLE),
     689             :     ATTRIBUTE_NAME(TRUE),
     690             :     ATTRIBUTE_NAME(FALSE),
     691             :     ATTRIBUTE_NAME(UNUSED),
     692             :     ATTRIBUTE_NAME(DYNAMIC),
     693             :     ATTRIBUTE_NAME(FOREACH),
     694             :     ATTRIBUTE_NAME(NOBREAK),
     695             :     ATTRIBUTE_NAME(AUTOBREAK),
     696             :     ATTRIBUTE_NAME(DEFINED)
     697             : };
     698             : size_t const g_attribute_table_size = sizeof(g_attribute_table) / sizeof(g_attribute_table[0]);
     699             : 
     700             : 
     701       16384 : as2js::Node::attribute_t str_to_attribute_code(as2js::String const& attr_name)
     702             : {
     703      425984 :     for(size_t idx(0); idx < g_attribute_table_size; ++idx)
     704             :     {
     705      425984 :         if(attr_name == g_attribute_table[idx].f_name)
     706             :         {
     707       16384 :             return g_attribute_table[idx].f_attribute;
     708             :         }
     709             :     }
     710           0 :     CPPUNIT_ASSERT(!"attribute code not found, test_as2js_compiler.cpp bug");
     711           0 :     return as2js::Node::attribute_t::NODE_ATTR_max;
     712             : }
     713             : 
     714             : 
     715           0 : as2js::String attribute_to_str(as2js::Node::attribute_t& attr)
     716             : {
     717           0 :     for(size_t idx(0); idx < g_attribute_table_size; ++idx)
     718             :     {
     719           0 :         if(attr == g_attribute_table[idx].f_attribute)
     720             :         {
     721           0 :             return g_attribute_table[idx].f_name;
     722             :         }
     723             :     }
     724           0 :     CPPUNIT_ASSERT(!"attribute code not found, test_as2js_compiler.cpp bug");
     725           0 :     return "";
     726             : }
     727             : 
     728             : 
     729             : 
     730             : 
     731       65536 : void verify_attributes(as2js::Node::pointer_t node, as2js::String const& attributes_set, bool verbose)
     732             : {
     733             :     // list of attributes that have to be set
     734       65536 :     std::vector<as2js::Node::attribute_t> attrs;
     735       65536 :     as2js::as_char_t const *a(attributes_set.c_str());
     736       65536 :     as2js::as_char_t const *s(a);
     737             :     for(;;)
     738             :     {
     739      180224 :         if(*a == ',' || *a == '\0')
     740             :         {
     741       65536 :             if(s == a)
     742             :             {
     743      114688 :                 break;
     744             :             }
     745       16384 :             as2js::String name(s, a - s);
     746       16384 :             attrs.push_back(str_to_attribute_code(name));
     747       16384 :             if(*a == '\0')
     748             :             {
     749       16384 :                 break;
     750             :             }
     751           0 :             do // skip commas
     752             :             {
     753           0 :                 ++a;
     754             :             }
     755           0 :             while(*a == ',');
     756           0 :             s = a;
     757             :         }
     758             :         else
     759             :         {
     760      114688 :             ++a;
     761             :         }
     762      114688 :     }
     763             : 
     764             :     // list of attributes that must be checked
     765      131072 :     std::vector<as2js::Node::attribute_t> attrs_to_check;
     766             : 
     767       65536 :     if(node->get_type() != as2js::Node::node_t::NODE_PROGRAM)
     768             :     {
     769             :         // except for PROGRAM, all attributes always apply
     770       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_PUBLIC);
     771       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_PRIVATE);
     772       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_PROTECTED);
     773       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_INTERNAL);
     774       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_TRANSIENT);
     775       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_VOLATILE);
     776       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_STATIC);
     777       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_ABSTRACT);
     778       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_VIRTUAL);
     779       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_ARRAY);
     780       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_REQUIRE_ELSE);
     781       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_ENSURE_THEN);
     782       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_NATIVE);
     783       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_DEPRECATED);
     784       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_UNSAFE);
     785       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_CONSTRUCTOR);
     786       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_FINAL);
     787       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_ENUMERABLE);
     788       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_TRUE);
     789       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_FALSE);
     790       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_UNUSED);
     791       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_DYNAMIC);
     792       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_FOREACH);
     793       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_NOBREAK);
     794       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_AUTOBREAK);
     795       49152 :         attrs_to_check.push_back(as2js::Node::attribute_t::NODE_ATTR_DEFINED);
     796             :     }
     797             : 
     798       65536 :     CPPUNIT_ASSERT(attrs.size() <= attrs_to_check.size());
     799             : 
     800     1343488 :     for(size_t idx(0); idx < attrs_to_check.size(); ++idx)
     801             :     {
     802     1277952 :         as2js::Node::attribute_t attr(attrs_to_check[idx]);
     803     1277952 :         std::vector<as2js::Node::attribute_t>::iterator it(std::find(attrs.begin(), attrs.end(), attr));
     804     1277952 :         if(it == attrs.end())
     805             :         {
     806             :             // expected to be unset
     807     1261568 :             if(verbose && node->get_attribute(attr))
     808             :             {
     809           0 :                 std::cerr << "*** Comparing attributes " << attribute_to_str(attr) << " (should not be set)\n";
     810             :             }
     811     1261568 :             CPPUNIT_ASSERT(!node->get_attribute(attr));
     812             :         }
     813             :         else
     814             :         {
     815             :             // expected to be set
     816       16384 :             attrs.erase(it);
     817       16384 :             if(verbose && !node->get_attribute(attr))
     818             :             {
     819           0 :                 std::cerr << "*** Comparing attributes " << attribute_to_str(attr) << " (it should be set in this case)\n";
     820             :             }
     821       16384 :             CPPUNIT_ASSERT(node->get_attribute(attr));
     822             :         }
     823             :     }
     824             : 
     825      131072 :     CPPUNIT_ASSERT(attrs.empty());
     826       65536 : }
     827             : 
     828             : 
     829             : 
     830             : 
     831       65536 : void verify_result(as2js::JSON::JSONValue::pointer_t expected, as2js::Node::pointer_t node, bool verbose)
     832             : {
     833       65536 :     as2js::String node_type_string;
     834       65536 :     node_type_string.from_utf8("node type");
     835      131072 :     as2js::String children_string;
     836       65536 :     children_string.from_utf8("children");
     837      131072 :     as2js::String link_strings[static_cast<int>(as2js::Node::link_t::LINK_max)];
     838       65536 :     link_strings[0].from_utf8("link instance");
     839       65536 :     link_strings[1].from_utf8("link type");
     840       65536 :     link_strings[2].from_utf8("link attributes");
     841       65536 :     link_strings[3].from_utf8("link goto exit");
     842       65536 :     link_strings[4].from_utf8("link goto enter");
     843      131072 :     as2js::String label_string;
     844       65536 :     label_string.from_utf8("label");
     845      131072 :     as2js::String flags_string;
     846       65536 :     flags_string.from_utf8("flags");
     847      131072 :     as2js::String attributes_string;
     848       65536 :     attributes_string.from_utf8("attributes");
     849      131072 :     as2js::String integer_string;
     850       65536 :     integer_string.from_utf8("integer");
     851      131072 :     as2js::String float_string;
     852       65536 :     float_string.from_utf8("float");
     853             : 
     854       65536 :     CPPUNIT_ASSERT(expected->get_type() == as2js::JSON::JSONValue::type_t::JSON_TYPE_OBJECT);
     855       65536 :     as2js::JSON::JSONValue::object_t const& child_object(expected->get_object());
     856             : 
     857       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_node_type(child_object.find(node_type_string));
     858       65536 :     if(it_node_type == child_object.end())
     859             :     {
     860           0 :         std::cerr << "\nerror: \"node type\" is mandatory in your JSON.\n";
     861           0 :         exit(1);
     862             :     }
     863      131072 :     as2js::JSON::JSONValue::pointer_t node_type_value(it_node_type->second);
     864       65536 :     if(verbose || node->get_type_name() != node_type_value->get_string())
     865             :     {
     866           0 :         std::cerr << "*** Comparing " << node->get_type_name() << " (node) vs " << node_type_value->get_string() << " (JSON)\n";
     867             :     }
     868       65536 :     CPPUNIT_ASSERT(node->get_type_name() == node_type_value->get_string());
     869             : 
     870       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_label(child_object.find(label_string));
     871       65536 :     if(it_label != child_object.end())
     872             :     {
     873             :         // we expect a string in this object
     874       16384 :         if(node->get_string() != it_label->second->get_string())
     875             :         {
     876           0 :             std::cerr << "   Expecting string \"" << it_label->second->get_string() << "\", node has \"" << node->get_string() << "\"\n";
     877             :         }
     878       16384 :         CPPUNIT_ASSERT(node->get_string() == it_label->second->get_string());
     879             :     }
     880             :     else
     881             :     {
     882             :         // the node cannot have a string otherwise, so we expect a throw
     883       49152 :         CPPUNIT_ASSERT_THROW(node->get_string(), as2js::exception_internal_error);
     884             :     }
     885             : 
     886       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_flags(child_object.find(flags_string));
     887       65536 :     if(it_flags != child_object.end())
     888             :     {
     889             :         // the tester declared as set of flags that are expected to be set
     890           0 :         verify_flags(node, it_flags->second->get_string(), verbose);
     891             :     }
     892             :     else
     893             :     {
     894             :         // all flags must be unset
     895       65536 :         verify_flags(node, "", verbose);
     896             :     }
     897             : 
     898             :     // WARNING: these attributes are what we call IMMEDIATE ATTRIBUTES in case
     899             :     //          of the parser because the parser also makes use of a
     900             :     //          LINK_ATTRIBUTES which represents a list of attributes
     901       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_attributes(child_object.find(attributes_string));
     902       65536 :     if(it_attributes != child_object.end())
     903             :     {
     904             :         // the tester declared as set of attributes that are expected to be set
     905       16384 :         verify_attributes(node, it_attributes->second->get_string(), verbose);
     906             :     }
     907             :     else
     908             :     {
     909             :         // all attributes must be unset
     910       49152 :         verify_attributes(node, "", verbose);
     911             :     }
     912             : 
     913       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_integer(child_object.find(integer_string));
     914       65536 :     if(it_integer != child_object.end())
     915             :     {
     916             :         // we expect an integer in this object
     917           0 :         if(node->get_int64().get() != it_integer->second->get_int64().get())
     918             :         {
     919           0 :             std::cerr << "   Expecting " << it_integer->second->get_int64().get() << ", got " << node->get_int64().get() << " in the node\n";
     920             :         }
     921           0 :         CPPUNIT_ASSERT(node->get_int64().get() == it_integer->second->get_int64().get());
     922             :     }
     923             :     else
     924             :     {
     925             :         // the node cannot have an integer otherwise, so we expect a throw
     926       65536 :         CPPUNIT_ASSERT_THROW(node->get_int64(), as2js::exception_internal_error);
     927             :     }
     928             : 
     929       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_float(child_object.find(float_string));
     930       65536 :     if(it_float != child_object.end())
     931             :     {
     932             :         // if we expect a NaN we have to compare specifically
     933             :         // because (NaN == NaN) always returns false
     934           0 :         if(it_float->second->get_float64().is_NaN())
     935             :         {
     936           0 :             CPPUNIT_ASSERT(node->get_float64().is_NaN());
     937             :         }
     938           0 :         else if(it_float->second->get_float64().is_positive_infinity())
     939             :         {
     940           0 :             CPPUNIT_ASSERT(node->get_float64().is_positive_infinity());
     941             :         }
     942           0 :         else if(it_float->second->get_float64().is_negative_infinity())
     943             :         {
     944           0 :             CPPUNIT_ASSERT(node->get_float64().is_negative_infinity());
     945             :         }
     946             :         else
     947             :         {
     948             :             // we expect a floating point in this object
     949           0 :             if(node->get_float64().get() - it_float->second->get_float64().get() > 0.0001)
     950             :             {
     951           0 :                 std::cerr << "   Expecting " << it_float->second->get_float64().get() << ", got " << node->get_float64().get() << " in the node\n";
     952             :             }
     953           0 :             CPPUNIT_ASSERT(node->get_float64().get() - it_float->second->get_float64().get() <= 0.0001);
     954             : 
     955             : #pragma GCC diagnostic push
     956             : #pragma GCC diagnostic ignored "-Wfloat-equal"
     957             :             // further, if the float is zero, it may be +0.0 or -0.0
     958           0 :             if(it_float->second->get_float64().get() == 0.0)
     959             :             {
     960           0 :                 CPPUNIT_ASSERT(std::signbit(node->get_float64().get()) == std::signbit(it_float->second->get_float64().get()));
     961             :             }
     962             : #pragma GCC diagnostic pop
     963             :         }
     964             :     }
     965             :     else
     966             :     {
     967             :         // the node cannot have a float otherwise, so we expect a throw
     968       65536 :         CPPUNIT_ASSERT_THROW(node->get_float64(), as2js::exception_internal_error);
     969             :     }
     970             : 
     971             :     // List of links are tested just like children, only the list starts somewhere else
     972      393216 :     for(int link_idx(0); link_idx < static_cast<int>(as2js::Node::link_t::LINK_max); ++link_idx)
     973             :     {
     974      327680 :         as2js::String link_name;
     975      327680 :         switch(static_cast<as2js::Node::link_t>(link_idx))
     976             :         {
     977             :         case as2js::Node::link_t::LINK_INSTANCE:
     978       65536 :             link_name = "instance";
     979       65536 :             break;
     980             : 
     981             :         case as2js::Node::link_t::LINK_TYPE:
     982       65536 :             link_name = "type";
     983       65536 :             break;
     984             : 
     985             :         case as2js::Node::link_t::LINK_ATTRIBUTES:
     986       65536 :             link_name = "attributes";
     987       65536 :             break;
     988             : 
     989             :         case as2js::Node::link_t::LINK_GOTO_EXIT:
     990       65536 :             link_name = "goto-exit";
     991       65536 :             break;
     992             : 
     993             :         case as2js::Node::link_t::LINK_GOTO_ENTER:
     994       65536 :             link_name = "goto-enter";
     995       65536 :             break;
     996             : 
     997             :         case as2js::Node::link_t::LINK_max:
     998           0 :             CPPUNIT_ASSERT(!"LINK_max reached when getting the link type");
     999           0 :             break;
    1000             : 
    1001             :         }
    1002      327680 :         as2js::JSON::JSONValue::object_t::const_iterator it_link(child_object.find(link_strings[link_idx]));
    1003      327680 :         as2js::Node::pointer_t link_node(node->get_link(static_cast<as2js::Node::link_t>(link_idx)));
    1004      327680 :         if(link_node)
    1005             :         {
    1006             :             // make sure root node is of the right type
    1007           0 :             switch(static_cast<as2js::Node::link_t>(link_idx))
    1008             :             {
    1009             :             case as2js::Node::link_t::LINK_INSTANCE:
    1010           0 :                 CPPUNIT_ASSERT(!"compiler does not use LINK_INSTANCE");
    1011           0 :                 break;
    1012             : 
    1013             :             case as2js::Node::link_t::LINK_TYPE:
    1014           0 :                 CPPUNIT_ASSERT(!"compiler does not use LINK_TYPE");
    1015           0 :                 break;
    1016             : 
    1017             :             case as2js::Node::link_t::LINK_ATTRIBUTES:
    1018           0 :                 CPPUNIT_ASSERT(link_node->get_type() == as2js::Node::node_t::NODE_ATTRIBUTES);
    1019           0 :                 break;
    1020             : 
    1021             :             case as2js::Node::link_t::LINK_GOTO_EXIT:
    1022           0 :                 CPPUNIT_ASSERT(!"compiler does not use LINK_GOTO_EXIT");
    1023           0 :                 break;
    1024             : 
    1025             :             case as2js::Node::link_t::LINK_GOTO_ENTER:
    1026           0 :                 CPPUNIT_ASSERT(!"compiler does not use LINK_GOTO_ENTER");
    1027           0 :                 break;
    1028             : 
    1029             :             case as2js::Node::link_t::LINK_max:
    1030           0 :                 CPPUNIT_ASSERT(!"LINK_max reached when testing the link_node type");
    1031           0 :                 break;
    1032             : 
    1033             :             }
    1034             :         }
    1035      327680 :         if(it_link != child_object.end())
    1036             :         {
    1037             :             // the children value must be an array
    1038           0 :             as2js::JSON::JSONValue::array_t const& array(it_link->second->get_array());
    1039           0 :             size_t const max_links(array.size());
    1040           0 :             if(link_node)
    1041             :             {
    1042           0 :                 if(verbose && max_links != link_node->get_children_size())
    1043             :                 {
    1044           0 :                     std::cerr << "   Expecting " << max_links << " " << link_name << ", we have " << link_node->get_children_size() << " in the node\n";
    1045             :                 }
    1046           0 :                 CPPUNIT_ASSERT(max_links == link_node->get_children_size());
    1047           0 :                 for(size_t idx(0); idx < max_links; ++idx)
    1048             :                 {
    1049           0 :                     as2js::JSON::JSONValue::pointer_t link_value(array[idx]);
    1050           0 :                     verify_result(link_value, link_node->get_child(idx), verbose); // recursive
    1051           0 :                 }
    1052             :             }
    1053             :             else
    1054             :             {
    1055           0 :                 if(verbose && max_links != 0)
    1056             :                 {
    1057           0 :                     std::cerr << "   Expecting " << max_links << " " << link_name << ", we have no " << link_name << " at all in the node\n";
    1058             :                 }
    1059           0 :                 CPPUNIT_ASSERT(max_links == 0);
    1060             :             }
    1061             :         }
    1062             :         else
    1063             :         {
    1064             :             // no children defined in the JSON, no children expected in the node
    1065      327680 :             if(verbose && link_node && link_node->get_children_size() != 0)
    1066             :             {
    1067           0 :                 std::cerr << "   Expecting no " << link_name << " list, we have " << link_node->get_children_size() << " " << link_name << " in the node\n";
    1068             :             }
    1069      327680 :             CPPUNIT_ASSERT(!link_node || link_node->get_children_size() == 0);
    1070             :         }
    1071      327680 :     }
    1072             : 
    1073       65536 :     as2js::JSON::JSONValue::object_t::const_iterator it_children(child_object.find(children_string));
    1074       65536 :     if(it_children != child_object.end())
    1075             :     {
    1076             :         // the children value must be an array
    1077       49152 :         as2js::JSON::JSONValue::array_t const& array(it_children->second->get_array());
    1078       49152 :         size_t const max_children(array.size());
    1079       49152 :         if(verbose && max_children != node->get_children_size())
    1080             :         {
    1081           0 :             std::cerr << "   Expecting " << max_children << " children, we have " << node->get_children_size() << " in the node\n";
    1082             :         }
    1083       49152 :         CPPUNIT_ASSERT(max_children == node->get_children_size());
    1084       98304 :         for(size_t idx(0); idx < max_children; ++idx)
    1085             :         {
    1086       49152 :             as2js::JSON::JSONValue::pointer_t children_value(array[idx]);
    1087       49152 :             verify_result(children_value, node->get_child(idx), verbose); // recursive
    1088       49152 :         }
    1089             :     }
    1090             :     else
    1091             :     {
    1092             :         // no children defined in the JSON, no children expected in the node
    1093       16384 :         if(verbose && node->get_children_size() != 0)
    1094             :         {
    1095           0 :             std::cerr << "   Expecting no children, we have " << node->get_children_size() << " in the node\n";
    1096             :         }
    1097       16384 :         CPPUNIT_ASSERT(node->get_children_size() == 0);
    1098       65536 :     }
    1099       65536 : }
    1100             : 
    1101             : 
    1102             : 
    1103           3 : class input_retriever : public as2js::InputRetriever
    1104             : {
    1105             : public:
    1106           0 :     virtual as2js::Input::pointer_t retrieve(as2js::String const& filename)
    1107             :     {
    1108           0 :         if(filename == "")
    1109             :         {
    1110             :         }
    1111             : 
    1112           0 :         return as2js::Input::pointer_t();
    1113             :     }
    1114             : 
    1115             : };
    1116             : 
    1117             : 
    1118        8193 : void init_rc()
    1119             : {
    1120        8193 :     g_created_files = true;
    1121             : 
    1122             :     // The .rc file cannot be captured by the input retriever
    1123             :     // so instead we create a file in the current directory
    1124             :     char pwd[PATH_MAX + 1];
    1125        8193 :     CPPUNIT_ASSERT(getcwd(pwd, sizeof(pwd)) == pwd);
    1126        8193 :     pwd[PATH_MAX] = '\0';
    1127        8193 :     as2js::String spwd;
    1128       16386 :     std::string tpwd;
    1129      311334 :     for(char const *s(pwd); *s != '\0'; ++s)
    1130             :     {
    1131      303141 :         if(*s == '\'') // just in case, but it probably will never happen...
    1132             :         {
    1133           0 :             tpwd += '\\';
    1134             :         }
    1135      303141 :         tpwd += *s;
    1136             :     }
    1137        8193 :     spwd.from_utf8(tpwd.c_str());
    1138       16386 :     as2js::String rc("// rc test file\n");
    1139             :     rc += "{\n"
    1140        8193 :           "  'scripts': '";
    1141        8193 :                 rc += spwd;
    1142             :                 rc += "/scripts',\n"
    1143        8193 :           "  'db': '";
    1144        8193 :                 rc += spwd;
    1145             :                 rc += "/test.db',\n"
    1146             :           "  'temporary_variable_name': '@temp$'\n"
    1147        8193 :           "}\n";
    1148             : 
    1149        8193 :     mkdir("as2js", 0700);
    1150       16386 :     as2js::FileOutput output;
    1151        8193 :     CPPUNIT_ASSERT(output.open("as2js/as2js.rc"));
    1152       16386 :     output.write(rc);
    1153        8193 : }
    1154             : 
    1155             : 
    1156           1 : void init_compiler(as2js::Compiler& compiler)
    1157             : {
    1158             :     // The .rc file cannot be captured by the input retriever
    1159             :     // so instead we create a file in the current directory
    1160             : 
    1161             :     // setup an input retriever which in most cases just returns nullptr
    1162           1 :     compiler.set_input_retriever(as2js::InputRetriever::pointer_t(new input_retriever));
    1163           1 : }
    1164             : 
    1165             : 
    1166             : 
    1167             : //
    1168             : // JSON data used to test the compiler, most of the work is in this table
    1169             : // these are long JSON strings! It is actually generated using the
    1170             : // json_to_string tool and the test_as2js_compiler_*.json source files.
    1171             : //
    1172             : // Note: the top entries are arrays so we can execute programs in the
    1173             : //       order we define them...
    1174             : //
    1175             : char const g_compiler_class[] =
    1176             : #include "test_as2js_compiler_class.ci"
    1177             : ;
    1178             : //char const g_compiler_assignments[] =
    1179             : //#include "test_as2js_compiler_assignments.ci"
    1180             : //;
    1181             : //char const g_compiler_bitwise[] =
    1182             : //#include "test_as2js_compiler_bitwise.ci"
    1183             : //;
    1184             : //char const g_compiler_compare[] =
    1185             : //#include "test_as2js_compiler_compare.ci"
    1186             : //;
    1187             : //char const g_compiler_conditional[] =
    1188             : //#include "test_as2js_compiler_conditional.ci"
    1189             : //;
    1190             : //char const g_compiler_equality[] =
    1191             : //#include "test_as2js_compiler_equality.ci"
    1192             : //;
    1193             : //char const g_compiler_logical[] =
    1194             : //#include "test_as2js_compiler_logical.ci"
    1195             : //;
    1196             : //char const g_compiler_match[] =
    1197             : //#include "test_as2js_compiler_match.ci"
    1198             : //;
    1199             : //char const g_compiler_multiplicative[] =
    1200             : //#include "test_as2js_compiler_multiplicative.ci"
    1201             : //;
    1202             : //char const g_compiler_relational[] =
    1203             : //#include "test_as2js_compiler_relational.ci"
    1204             : //;
    1205             : //char const g_compiler_statements[] =
    1206             : //#include "test_as2js_compiler_statements.ci"
    1207             : //;
    1208             : 
    1209             : 
    1210             : 
    1211             : 
    1212             : 
    1213             : 
    1214             : 
    1215             : 
    1216             : // This function runs all the tests defined in the
    1217             : // string 'data'
    1218           1 : void run_tests(char const *data, char const *filename)
    1219             : {
    1220           1 :     as2js::String input_data;
    1221           1 :     input_data.from_utf8(data);
    1222             : 
    1223           1 :     if(as2js_test::g_save_parser_tests)
    1224             :     {
    1225           0 :         std::ofstream json_file;
    1226           0 :         json_file.open(filename);
    1227           0 :         CPPUNIT_ASSERT(json_file.is_open());
    1228           0 :         json_file << "// To properly indent this JSON you may use http://json-indent.appspot.com/"
    1229           0 :                 << std::endl << data << std::endl;
    1230             :     }
    1231             : 
    1232           2 :     as2js::StringInput::pointer_t in(new as2js::StringInput(input_data));
    1233           2 :     as2js::JSON::pointer_t json_data(new as2js::JSON);
    1234           2 :     as2js::JSON::JSONValue::pointer_t json(json_data->parse(in));
    1235             : 
    1236             :     // verify that the compiler() did not fail
    1237           1 :     CPPUNIT_ASSERT(!!json);
    1238           1 :     CPPUNIT_ASSERT(json->get_type() == as2js::JSON::JSONValue::type_t::JSON_TYPE_ARRAY);
    1239             : 
    1240           2 :     as2js::String name_string;
    1241           1 :     name_string.from_utf8("name");
    1242           2 :     as2js::String program_string;
    1243           1 :     program_string.from_utf8("program");
    1244           2 :     as2js::String verbose_string;
    1245           1 :     verbose_string.from_utf8("verbose");
    1246           2 :     as2js::String slow_string;
    1247           1 :     slow_string.from_utf8("slow");
    1248           2 :     as2js::String parser_result_string;
    1249           1 :     parser_result_string.from_utf8("parser result");
    1250           2 :     as2js::String compiler_result_string;
    1251           1 :     compiler_result_string.from_utf8("compiler result");
    1252           2 :     as2js::String expected_messages_string;
    1253           1 :     expected_messages_string.from_utf8("expected messages");
    1254             : 
    1255           1 :     std::cout << "\n";
    1256             : 
    1257           1 :     as2js::JSON::JSONValue::array_t const& array(json->get_array());
    1258           1 :     size_t const max_programs(array.size());
    1259           2 :     for(size_t idx(0); idx < max_programs; ++idx)
    1260             :     {
    1261           1 :         as2js::JSON::JSONValue::pointer_t prog_obj(array[idx]);
    1262           1 :         CPPUNIT_ASSERT(prog_obj->get_type() == as2js::JSON::JSONValue::type_t::JSON_TYPE_OBJECT);
    1263           1 :         as2js::JSON::JSONValue::object_t const& prog(prog_obj->get_object());
    1264             : 
    1265           1 :         bool verbose(false);
    1266           1 :         as2js::JSON::JSONValue::object_t::const_iterator verbose_it(prog.find(verbose_string));
    1267           1 :         if(verbose_it != prog.end())
    1268             :         {
    1269           0 :             verbose = verbose_it->second->get_type() == as2js::JSON::JSONValue::type_t::JSON_TYPE_TRUE;
    1270             :         }
    1271             : 
    1272           1 :         bool slow(false);
    1273           1 :         as2js::JSON::JSONValue::object_t::const_iterator slow_it(prog.find(slow_string));
    1274           1 :         if(slow_it != prog.end())
    1275             :         {
    1276           1 :             slow = slow_it->second->get_type() == as2js::JSON::JSONValue::type_t::JSON_TYPE_TRUE;
    1277             :         }
    1278             : 
    1279             :         // got a program, try to compile it with all the possible options
    1280           2 :         as2js::JSON::JSONValue::pointer_t name(prog.find(name_string)->second);
    1281           1 :         std::cout << "  -- working on \"" << name->get_string() << "\" " << (slow ? "" : "...") << std::flush;
    1282             : 
    1283        8193 :         for(size_t opt(0); opt < (1 << g_options_size); ++opt)
    1284             :         {
    1285        8192 :             if(slow && ((opt + 1) % 250) == 0)
    1286             :             {
    1287          32 :                 std::cout << "." << std::flush;
    1288             :             }
    1289             : //std::cerr << "\n***\n*** OPTIONS:";
    1290        8192 :             as2js::Options::pointer_t options(new as2js::Options);
    1291      114688 :             for(size_t o(0); o < g_options_size; ++o)
    1292             :             {
    1293      106496 :                 if((opt & (1 << o)) != 0)
    1294             :                 {
    1295             :                     options->set_option(g_options[o].f_option,
    1296       53248 :                             options->get_option(g_options[o].f_option) | g_options[o].f_value);
    1297             : //std::cerr << " " << g_options[o].f_name << "=" << g_options[o].f_value;
    1298             :                 }
    1299             :             }
    1300             : //std::cerr << "\n***\n";
    1301             : 
    1302       16384 :             as2js::JSON::JSONValue::pointer_t program_value(prog.find(program_string)->second);
    1303       16384 :             as2js::String program_source(program_value->get_string());
    1304             : //std::cerr << "prog = [" << program_source << "]\n";
    1305       16384 :             as2js::StringInput::pointer_t prog_text(new as2js::StringInput(program_source));
    1306       16384 :             as2js::Parser::pointer_t parser(new as2js::Parser(prog_text, options));
    1307             : 
    1308        8192 :             init_rc();
    1309       16384 :             test_callback tc(verbose);
    1310             : 
    1311             :             // no errors exepected while parsing (if you want to test errors
    1312             :             // in the parser, use the test_as2js_parser.cpp test instead)
    1313       16384 :             as2js::Node::pointer_t root(parser->parse());
    1314             : 
    1315             :             // verify the parser result, that way we can make sure we are
    1316             :             // testing the tree we want to test with the compiler
    1317        8192 :             verify_result(prog.find(parser_result_string)->second, root, verbose);
    1318             : 
    1319             :             // now the compiler may end up generating messages...
    1320        8192 :             as2js::JSON::JSONValue::object_t::const_iterator expected_msg_it(prog.find(expected_messages_string));
    1321        8192 :             if(expected_msg_it != prog.end())
    1322             :             {
    1323             : 
    1324             :                 // the expected messages value must be an array
    1325           0 :                 as2js::JSON::JSONValue::array_t const& msg_array(expected_msg_it->second->get_array());
    1326           0 :                 size_t const max_msgs(msg_array.size());
    1327           0 :                 for(size_t j(0); j < max_msgs; ++j)
    1328             :                 {
    1329           0 :                     as2js::JSON::JSONValue::pointer_t message_value(msg_array[j]);
    1330           0 :                     as2js::JSON::JSONValue::object_t const& message(message_value->get_object());
    1331             : 
    1332           0 :                     as2js::JSON::JSONValue::object_t::const_iterator const message_options_iterator(message.find("options"));
    1333           0 :                     if(message_options_iterator != message.end())
    1334             :                     {
    1335             : //{
    1336             : //as2js::JSON::JSONValue::object_t::const_iterator line_it(message.find("line #"));
    1337             : //if(line_it != message.end())
    1338             : //{
    1339             : //    int64_t lines(line_it->second->get_int64().get());
    1340             : //std::cerr << "_________\nLine #" << lines << "\n";
    1341             : //}
    1342             : //else
    1343             : //std::cerr << "_________\nLine #<undefined>\n";
    1344             : //}
    1345           0 :                         test_callback::expected_t expected;
    1346           0 :                         expected.f_message_level = static_cast<as2js::message_level_t>(message.find("message level")->second->get_int64().get());
    1347           0 :                         expected.f_error_code = str_to_error_code(message.find("error code")->second->get_string());
    1348           0 :                         expected.f_pos.set_filename("unknown-file");
    1349           0 :                         as2js::JSON::JSONValue::object_t::const_iterator func_it(message.find("function name"));
    1350           0 :                         if(func_it == message.end())
    1351             :                         {
    1352           0 :                             expected.f_pos.set_function("unknown-func");
    1353             :                         }
    1354             :                         else
    1355             :                         {
    1356           0 :                             expected.f_pos.set_function(func_it->second->get_string());
    1357             :                         }
    1358           0 :                         as2js::JSON::JSONValue::object_t::const_iterator line_it(message.find("line #"));
    1359           0 :                         if(line_it != message.end())
    1360             :                         {
    1361           0 :                             int64_t lines(line_it->second->get_int64().get());
    1362           0 :                             for(int64_t l(1); l < lines; ++l)
    1363             :                             {
    1364           0 :                                 expected.f_pos.new_line();
    1365             :                             }
    1366             :                         }
    1367           0 :                         expected.f_message = message.find("message")->second->get_string();
    1368           0 :                         tc.f_expected.push_back(expected);
    1369             :                     }
    1370           0 :                 }
    1371             :             }
    1372             : 
    1373             :             // run the compiler
    1374       16384 :             as2js::Compiler compiler(options);
    1375        8192 :             compiler.compile(root);
    1376             : 
    1377        8192 :             tc.got_called();
    1378             : 
    1379             :             // the result is object which can have children
    1380             :             // which are represented by an array of objects
    1381        8192 :             verify_result(prog.find(compiler_result_string)->second, root, verbose);
    1382        8192 :         }
    1383             : 
    1384           1 :         std::cout << " OK\n";
    1385           2 :     }
    1386           1 : }
    1387             : 
    1388             : 
    1389             : }
    1390             : // no name namespace
    1391             : 
    1392             : 
    1393           2 : void As2JsCompilerUnitTests::setUp()
    1394             : {
    1395             :     // verify that this user does not have existing rc files because
    1396             :     // that can interfer with the tests! (and we do not want to delete
    1397             :     // those under his/her feet)
    1398             : 
    1399             :     // AS2JS_RC variable
    1400           2 :     CPPUNIT_ASSERT(getenv("AS2JS_RC") == nullptr);
    1401             : 
    1402             :     // local file
    1403             :     struct stat st;
    1404           2 :     CPPUNIT_ASSERT(stat("as2js/as2js.rc", &st) == -1);
    1405             : 
    1406             :     // user defined .config file
    1407           2 :     as2js::String home;
    1408           2 :     home.from_utf8(getenv("HOME"));
    1409           4 :     as2js::String config(home);
    1410           2 :     config += "/.config/as2js/as2js.rc";
    1411           4 :     std::string cfg(config.to_utf8());
    1412           2 :     CPPUNIT_ASSERT(stat(cfg.c_str(), &st) == -1);
    1413             : 
    1414             :     // system defined configuration file
    1415           2 :     CPPUNIT_ASSERT(stat("/etc/as2js/as2js.rc", &st) == -1);
    1416             : 
    1417             :     // we do not want a test.db or it could conflict with this test
    1418           2 :     CPPUNIT_ASSERT(stat("test.db", &st) == -1);
    1419             : 
    1420             :     // Now check that we have the scripts directories, we expect
    1421             :     // the test to be run from the root directory of the source
    1422             :     // tree, although if you have different scripts you could run
    1423             :     // from somewhere else, only make sure those scripts are somehow
    1424             :     // accessible
    1425           2 :     CPPUNIT_ASSERT(stat("scripts", &st) == 0);
    1426           2 :     CPPUNIT_ASSERT(stat("scripts/extensions", &st) == 0);
    1427           2 :     CPPUNIT_ASSERT(stat("scripts/global", &st) == 0);
    1428           2 :     CPPUNIT_ASSERT(stat("scripts/native", &st) == 0);
    1429           4 :     CPPUNIT_ASSERT(stat("scripts/system", &st) == 0);
    1430           2 : }
    1431             : 
    1432             : 
    1433           2 : void As2JsCompilerUnitTests::tearDown()
    1434             : {
    1435           2 :     if(g_created_files)
    1436             :     {
    1437             :         // ignore errors on these few calls
    1438           2 :         unlink("test.db");
    1439           2 :         unlink("as2js/as2js.rc");
    1440           2 :         rmdir("as2js");
    1441             :     }
    1442           2 : }
    1443             : 
    1444             : 
    1445           1 : void As2JsCompilerUnitTests::test_compiler_invalid_nodes()
    1446             : {
    1447             :     // empty node does absolutely nothing
    1448             :     {
    1449           1 :         as2js::Node::pointer_t node;
    1450           1 :         init_rc();
    1451           2 :         test_callback tc(false);
    1452           2 :         as2js::Options::pointer_t options(new as2js::Options);
    1453             : 
    1454           2 :         as2js::Compiler compiler(options);
    1455           1 :         init_compiler(compiler);
    1456           2 :         CPPUNIT_ASSERT(compiler.compile(node) == 0);
    1457             :     }
    1458             : 
    1459             :     // all node types other than ROOT and PROGRAM generate an error
    1460        1147 :     for(int i(-1); i < static_cast<int>(as2js::Node::node_t::NODE_max); ++i)
    1461             :     {
    1462        1146 :         as2js::Node::pointer_t node;
    1463             :         try
    1464             :         {
    1465        1146 :             node.reset(new as2js::Node(as2js::Node::node_t::NODE_UNKNOWN));
    1466             :         }
    1467             :         catch(as2js::exception_incompatible_node_type&)
    1468             :         {
    1469             :             // many node types cannot be created (we have gaps in our numbers)
    1470             :             continue;
    1471             :         }
    1472             : 
    1473        2292 :         test_callback tc(false);
    1474             :         {
    1475        1146 :             test_callback::expected_t expected;
    1476        1146 :             expected.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
    1477        1146 :             expected.f_error_code = as2js::err_code_t::AS_ERR_INTERNAL_ERROR;
    1478        1146 :             expected.f_pos.set_filename("unknown-file");
    1479        1146 :             expected.f_pos.set_function("unknown-func");
    1480             :             //expected.f_pos.new_line(); -- line 1
    1481        1146 :             expected.f_message = "the Compiler::compile() function expected a root or a program node to start with.";
    1482        1146 :             tc.f_expected.push_back(expected);
    1483             :         }
    1484             : 
    1485        2292 :         as2js::Options::pointer_t options(new as2js::Options);
    1486        2292 :         as2js::Compiler compiler(options);
    1487        1146 :         CPPUNIT_ASSERT(compiler.compile(node) != 0);
    1488        1146 :         CPPUNIT_ASSERT(node->get_type() == as2js::Node::node_t::NODE_UNKNOWN);
    1489        1146 :         CPPUNIT_ASSERT(node->get_children_size() == 0);
    1490        1146 :     }
    1491           1 : }
    1492             : 
    1493             : 
    1494           1 : void As2JsCompilerUnitTests::test_compiler_class()
    1495             : {
    1496           1 :     run_tests(g_compiler_class, "test_compiler_class.json");
    1497          13 : }
    1498             : 
    1499             : //void As2JsCompilerUnitTests::test_compiler_assignments()
    1500             : //{
    1501             : //    run_tests(g_compiler_assignments, "test_compiler_assignments.json");
    1502             : //}
    1503             : //
    1504             : //void As2JsCompilerUnitTests::test_compiler_bitwise()
    1505             : //{
    1506             : //    run_tests(g_compiler_bitwise, "test_compiler_bitwise.json");
    1507             : //}
    1508             : //
    1509             : //void As2JsCompilerUnitTests::test_compiler_compare()
    1510             : //{
    1511             : //    run_tests(g_compiler_compare, "test_compiler_compare.json");
    1512             : //}
    1513             : //
    1514             : //void As2JsCompilerUnitTests::test_compiler_conditional()
    1515             : //{
    1516             : //    run_tests(g_compiler_conditional, "test_compiler_conditional.json");
    1517             : //}
    1518             : //
    1519             : //void As2JsCompilerUnitTests::test_compiler_equality()
    1520             : //{
    1521             : //    run_tests(g_compiler_equality, "test_compiler_equality.json");
    1522             : //}
    1523             : //
    1524             : //void As2JsCompilerUnitTests::test_compiler_logical()
    1525             : //{
    1526             : //    run_tests(g_compiler_logical, "test_compiler_logical.json");
    1527             : //}
    1528             : //
    1529             : //void As2JsCompilerUnitTests::test_compiler_match()
    1530             : //{
    1531             : //// regex is not well supported before 4.9.0
    1532             : //#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
    1533             : //    run_tests(g_compiler_match, "test_compiler_match.json");
    1534             : //#else
    1535             : //    std::cerr << " -- warning: test As2JsOptimizerUnitTests::test_compiler_match() skip since you are compiling with a g++ version prior to 4.9.0" << std::endl;
    1536             : //#endif
    1537             : //}
    1538             : //
    1539             : //void As2JsCompilerUnitTests::test_compiler_multiplicative()
    1540             : //{
    1541             : //    run_tests(g_compiler_multiplicative, "test_compiler_multiplicative.json");
    1542             : //}
    1543             : //
    1544             : //void As2JsCompilerUnitTests::test_compiler_relational()
    1545             : //{
    1546             : //    run_tests(g_compiler_relational, "test_compiler_relational.json");
    1547             : //}
    1548             : //
    1549             : //void As2JsCompilerUnitTests::test_compiler_statements()
    1550             : //{
    1551             : //    run_tests(g_compiler_statements, "test_compiler_statements.json");
    1552             : //}
    1553             : 
    1554             : 
    1555             : 
    1556             : 
    1557             : 
    1558             : 
    1559             : 
    1560             : 
    1561             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10