LCOV - code coverage report
Current view: top level - tests - test_as2js_db.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 537 544 98.7 %
Date: 2014-11-22 Functions: 21 22 95.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* test_as2js_db.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_db.h"
      37             : #include    "test_as2js_main.h"
      38             : 
      39             : #include    "db.h"
      40             : #include    "as2js/exceptions.h"
      41             : #include    "as2js/message.h"
      42             : 
      43             : #include    <controlled_vars/controlled_vars_limited_auto_enum_init.h>
      44             : 
      45             : #include    <unistd.h>
      46             : #include    <sys/stat.h>
      47             : 
      48             : #include    <cstring>
      49             : #include    <algorithm>
      50             : #include    <iomanip>
      51             : 
      52             : #include    <cppunit/config/SourcePrefix.h>
      53           4 : CPPUNIT_TEST_SUITE_REGISTRATION( As2JsDBUnitTests );
      54             : 
      55             : namespace
      56             : {
      57             : 
      58             : 
      59        4808 : int32_t generate_string(as2js::String& str)
      60             : {
      61             :     as2js::as_char_t c;
      62        4808 :     int32_t used(0);
      63        4808 :     int ctrl(rand() % 7);
      64        4808 :     int const max_chars(rand() % 25 + 20);
      65      159429 :     for(int j(0); j < max_chars; ++j)
      66             :     {
      67      241746 :         do
      68             :         {
      69      241746 :             c = rand() & 0x1FFFFF;
      70      241746 :             if(ctrl == 0)
      71             :             {
      72       59618 :                 ctrl = rand() % 7;
      73       59618 :                 if((ctrl & 3) == 1)
      74             :                 {
      75       17125 :                     c = c & 1 ? '"' : '\'';
      76             :                 }
      77             :                 else
      78             :                 {
      79       42493 :                     c &= 0x1F;
      80             :                 }
      81             :             }
      82             :             else
      83             :             {
      84      182128 :                 --ctrl;
      85             :             }
      86             :         }
      87             :         while(c >= 0x110000
      88      156178 :            || (c >= 0xD800 && c <= 0xDFFF)
      89      155996 :            || ((c & 0xFFFE) == 0xFFFE)
      90      155996 :            || c == '\0');
      91      154621 :         str += c;
      92      154621 :         switch(c)
      93             :         {
      94             :         case '\b':
      95        1393 :             used |= 0x01;
      96        1393 :             break;
      97             : 
      98             :         case '\f':
      99        1333 :             used |= 0x02;
     100        1333 :             break;
     101             : 
     102             :         case '\n':
     103        1320 :             used |= 0x04;
     104        1320 :             break;
     105             : 
     106             :         case '\r':
     107        1331 :             used |= 0x08;
     108        1331 :             break;
     109             : 
     110             :         case '\t':
     111        1317 :             used |= 0x10;
     112        1317 :             break;
     113             : 
     114             :         case '"':
     115        8708 :             used |= 0x20;
     116        8708 :             break;
     117             : 
     118             :         case '\'':
     119        8417 :             used |= 0x40;
     120        8417 :             break;
     121             : 
     122             :         default:
     123      130802 :             if(c < 0x0020)
     124             :             {
     125             :                 // other controls must be escaped using Unicode
     126       34426 :                 used |= 0x80;
     127             :             }
     128      130802 :             break;
     129             : 
     130             :         }
     131             :     }
     132             : 
     133        4808 :     return used;
     134             : }
     135             : 
     136             : 
     137             : class test_callback : public as2js::MessageCallback
     138             : {
     139             : public:
     140           4 :     test_callback()
     141           4 :     {
     142           4 :         as2js::Message::set_message_callback(this);
     143           4 :         g_warning_count = as2js::Message::warning_count();
     144           4 :         g_error_count = as2js::Message::error_count();
     145           4 :     }
     146             : 
     147           4 :     ~test_callback()
     148           8 :     {
     149             :         // make sure the pointer gets reset!
     150           4 :         as2js::Message::set_message_callback(nullptr);
     151           4 :     }
     152             : 
     153             :     // implementation of the output
     154           8 :     virtual void output(as2js::message_level_t message_level, as2js::err_code_t error_code, as2js::Position const& pos, std::string const& message)
     155             :     {
     156           8 :         CPPUNIT_ASSERT(!f_expected.empty());
     157             : 
     158             : //std::cerr << "filename = " << pos.get_filename() << " / " << f_expected[0].f_pos.get_filename() << "\n";
     159             : //std::cerr << "msg = " << message << " / " << f_expected[0].f_message << "\n";
     160             : //std::cerr << "page = " << pos.get_page() << " / " << f_expected[0].f_pos.get_page() << "\n";
     161             : //std::cerr << "line = " << pos.get_line() << " / " << f_expected[0].f_pos.get_line() << "\n";
     162             : //std::cerr << "error_code = " << static_cast<int>(error_code) << " / " << static_cast<int>(f_expected[0].f_error_code) << "\n";
     163             : 
     164           8 :         CPPUNIT_ASSERT(f_expected[0].f_call);
     165           8 :         CPPUNIT_ASSERT(message_level == f_expected[0].f_message_level);
     166           8 :         CPPUNIT_ASSERT(error_code == f_expected[0].f_error_code);
     167           8 :         CPPUNIT_ASSERT(pos.get_filename() == f_expected[0].f_pos.get_filename());
     168           8 :         CPPUNIT_ASSERT(pos.get_function() == f_expected[0].f_pos.get_function());
     169           8 :         CPPUNIT_ASSERT(pos.get_page() == f_expected[0].f_pos.get_page());
     170           8 :         CPPUNIT_ASSERT(pos.get_page_line() == f_expected[0].f_pos.get_page_line());
     171           8 :         CPPUNIT_ASSERT(pos.get_paragraph() == f_expected[0].f_pos.get_paragraph());
     172           8 :         CPPUNIT_ASSERT(pos.get_line() == f_expected[0].f_pos.get_line());
     173           8 :         CPPUNIT_ASSERT(message == f_expected[0].f_message);
     174             : 
     175           8 :         if(message_level == as2js::message_level_t::MESSAGE_LEVEL_WARNING)
     176             :         {
     177           0 :             ++g_warning_count;
     178           0 :             CPPUNIT_ASSERT(g_warning_count == as2js::Message::warning_count());
     179             :         }
     180             : 
     181           8 :         if(message_level == as2js::message_level_t::MESSAGE_LEVEL_FATAL
     182           8 :         || message_level == as2js::message_level_t::MESSAGE_LEVEL_ERROR)
     183             :         {
     184           8 :             ++g_error_count;
     185             : //std::cerr << "error: " << g_error_count << " / " << as2js::Message::error_count() << "\n";
     186           8 :             CPPUNIT_ASSERT(g_error_count == as2js::Message::error_count());
     187             :         }
     188             : 
     189           8 :         f_expected.erase(f_expected.begin());
     190           8 :     }
     191             : 
     192           4 :     void got_called()
     193             :     {
     194           4 :         if(!f_expected.empty())
     195             :         {
     196           0 :             std::cerr << "\n*** STILL " << f_expected.size() << " EXPECTED ***\n";
     197           0 :             std::cerr << "filename = " << f_expected[0].f_pos.get_filename() << "\n";
     198           0 :             std::cerr << "msg = " << f_expected[0].f_message << "\n";
     199           0 :             std::cerr << "page = " << f_expected[0].f_pos.get_page() << "\n";
     200           0 :             std::cerr << "error_code = " << static_cast<int>(f_expected[0].f_error_code) << "\n";
     201             :         }
     202           4 :         CPPUNIT_ASSERT(f_expected.empty());
     203           4 :     }
     204             : 
     205          50 :     struct expected_t
     206             :     {
     207             :         controlled_vars::tlbool_t   f_call;
     208             :         as2js::message_level_t      f_message_level;
     209             :         as2js::err_code_t           f_error_code;
     210             :         as2js::Position             f_pos;
     211             :         std::string                 f_message; // UTF-8 string
     212             :     };
     213             : 
     214             :     std::vector<expected_t>     f_expected;
     215             : 
     216             :     static controlled_vars::zint32_t   g_warning_count;
     217             :     static controlled_vars::zint32_t   g_error_count;
     218             : };
     219             : 
     220           4 : controlled_vars::zint32_t   test_callback::g_warning_count;
     221           4 : controlled_vars::zint32_t   test_callback::g_error_count;
     222             : 
     223           4 : controlled_vars::zint32_t   g_empty_home_too_late;
     224             : 
     225             : }
     226             : // no name namespace
     227             : 
     228             : 
     229             : 
     230             : 
     231           4 : void As2JsDBUnitTests::setUp()
     232             : {
     233             :     // we do not want a test.db or it would conflict with this test
     234             :     struct stat st;
     235           4 :     CPPUNIT_ASSERT(stat("test.db", &st) == -1);
     236           4 : }
     237             : 
     238             : 
     239           1 : void As2JsDBUnitTests::test_match()
     240             : {
     241         101 :     for(size_t idx(0); idx < 100; ++idx)
     242             :     {
     243         100 :         as2js::String start;
     244         100 :         generate_string(start);
     245         200 :         as2js::String middle;
     246         100 :         generate_string(middle);
     247         200 :         as2js::String end;
     248         100 :         generate_string(end);
     249             : 
     250         200 :         as2js::String name;
     251         100 :         name = start + middle + end;
     252         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, "*"));
     253             : 
     254         200 :         as2js::String p1(start);
     255         100 :         p1 += '*';
     256         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p1));
     257             : 
     258         200 :         as2js::String p2(start);
     259         100 :         p2 += '*';
     260         100 :         p2 += middle;
     261         100 :         p2 += '*';
     262         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p2));
     263             : 
     264         200 :         as2js::String p3(start);
     265         100 :         p3 += '*';
     266         100 :         p3 += end;
     267         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p3));
     268             : 
     269         200 :         as2js::String p4;
     270         100 :         p4 += '*';
     271         100 :         p4 += middle;
     272         100 :         p4 += '*';
     273         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p4));
     274             : 
     275         200 :         as2js::String p5;
     276         100 :         p5 += '*';
     277         100 :         p5 += middle;
     278         100 :         p5 += '*';
     279         100 :         p5 += end;
     280         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p5));
     281             : 
     282         200 :         as2js::String p6(start);
     283         100 :         p6 += '*';
     284         100 :         p6 += middle;
     285         100 :         p6 += '*';
     286         100 :         p6 += end;
     287         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p6));
     288             : 
     289         200 :         as2js::String p7;
     290         100 :         p7 += '*';
     291         100 :         p7 += end;
     292         100 :         CPPUNIT_ASSERT(as2js::Database::match_pattern(name, p7));
     293         100 :     }
     294           1 : }
     295             : 
     296             : 
     297           1 : void As2JsDBUnitTests::test_element()
     298             : {
     299           1 :     int32_t used_type(0);
     300           1 :     int32_t used_filename(0);
     301         101 :     for(size_t idx(0); idx < 100 || used_type != 0xFF || used_filename != 0xFF; ++idx)
     302             :     {
     303         100 :         as2js::Position pos;
     304             : 
     305         200 :         as2js::String raw_type;
     306         100 :         used_type |= generate_string(raw_type);
     307         200 :         as2js::JSON::JSONValue::pointer_t type(new as2js::JSON::JSONValue(pos, raw_type));
     308             : 
     309         200 :         as2js::String raw_filename;
     310         100 :         used_filename |= generate_string(raw_filename);
     311         200 :         as2js::JSON::JSONValue::pointer_t filename(new as2js::JSON::JSONValue(pos, raw_filename));
     312             : 
     313             :         // generate a line number
     314         100 :         int32_t raw_line((rand() & 0xFFFFFF) + 1);
     315         100 :         as2js::Int64 line_int64(raw_line);
     316         200 :         as2js::JSON::JSONValue::pointer_t line(new as2js::JSON::JSONValue(pos, line_int64));
     317             : 
     318         200 :         as2js::JSON::JSONValue::object_t obj;
     319         100 :         obj["filename"] = filename;
     320         100 :         obj["type"] = type;
     321         100 :         obj["line"] = line;
     322         200 :         as2js::JSON::JSONValue::pointer_t element(new as2js::JSON::JSONValue(pos, obj));
     323             : 
     324         200 :         as2js::Database::Element::pointer_t db_element(new as2js::Database::Element("this.is.an.element.name", element));
     325             : 
     326         100 :         CPPUNIT_ASSERT(db_element->get_element_name() == "this.is.an.element.name");
     327         100 :         CPPUNIT_ASSERT(db_element->get_type() == raw_type);
     328         100 :         CPPUNIT_ASSERT(db_element->get_filename() == raw_filename);
     329         100 :         CPPUNIT_ASSERT(db_element->get_line() == raw_line);
     330             : 
     331         100 :         generate_string(raw_type);
     332         100 :         db_element->set_type(raw_type);
     333         100 :         CPPUNIT_ASSERT(db_element->get_type() == raw_type);
     334             : 
     335         100 :         generate_string(raw_filename);
     336         100 :         db_element->set_filename(raw_filename);
     337         100 :         CPPUNIT_ASSERT(db_element->get_filename() == raw_filename);
     338             : 
     339         100 :         raw_line = (rand() & 0xFFFFFF) + 1;
     340         100 :         db_element->set_line(raw_line);
     341         100 :         CPPUNIT_ASSERT(db_element->get_line() == raw_line);
     342         100 :     }
     343             : 
     344             :     // now check for erroneous data
     345             :     {
     346           1 :         as2js::Position pos;
     347             : 
     348           2 :         as2js::String not_obj;
     349           1 :         generate_string(not_obj);
     350           2 :         as2js::JSON::JSONValue::pointer_t bad_element(new as2js::JSON::JSONValue(pos, not_obj));
     351             : 
     352           2 :         CPPUNIT_ASSERT_THROW(new as2js::Database::Element("expect.a.throw", bad_element), as2js::exception_internal_error);
     353             :     }
     354             : 
     355             :     {
     356           1 :         as2js::Position pos;
     357             : 
     358           1 :         int32_t bad_raw_type((rand() & 0xFFFFFF) + 1);
     359           1 :         as2js::Int64 bad_type_int64(bad_raw_type);
     360           2 :         as2js::JSON::JSONValue::pointer_t bad_type(new as2js::JSON::JSONValue(pos, bad_type_int64));
     361             : 
     362           1 :         double bad_raw_filename(static_cast<double>((rand() << 16) ^ rand()) / static_cast<double>((rand() << 16) ^ rand()));
     363           1 :         as2js::Float64 bad_filename_float64(bad_raw_filename);
     364           2 :         as2js::JSON::JSONValue::pointer_t bad_filename(new as2js::JSON::JSONValue(pos, bad_filename_float64));
     365             : 
     366             :         // generate a line number
     367           2 :         as2js::String bad_raw_line;
     368           1 :         generate_string(bad_raw_line);
     369           2 :         as2js::JSON::JSONValue::pointer_t bad_line(new as2js::JSON::JSONValue(pos, bad_raw_line));
     370             : 
     371           2 :         as2js::JSON::JSONValue::object_t bad_obj;
     372           1 :         bad_obj["filename"] = bad_filename;
     373           1 :         bad_obj["type"] = bad_type;
     374           1 :         bad_obj["line"] = bad_line;
     375           2 :         as2js::JSON::JSONValue::pointer_t element(new as2js::JSON::JSONValue(pos, bad_obj));
     376             : 
     377             :         // WARNING: errors should be generated in the order the elements
     378             :         //          appear in the map
     379           2 :         test_callback tc;
     380             : 
     381           2 :         test_callback::expected_t expected1;
     382           1 :         expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     383           1 :         expected1.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     384           1 :         expected1.f_pos.set_filename("unknown-file");
     385           1 :         expected1.f_pos.set_function("unknown-func");
     386           1 :         expected1.f_message = "The filename of an element in the database has to be a string.";
     387           1 :         tc.f_expected.push_back(expected1);
     388             : 
     389           2 :         test_callback::expected_t expected2;
     390           1 :         expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     391           1 :         expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     392           1 :         expected2.f_pos.set_filename("unknown-file");
     393           1 :         expected2.f_pos.set_function("unknown-func");
     394           1 :         expected2.f_message = "The line of an element in the database has to be an integer.";
     395           1 :         tc.f_expected.push_back(expected2);
     396             : 
     397           2 :         test_callback::expected_t expected3;
     398           1 :         expected3.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     399           1 :         expected3.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     400           1 :         expected3.f_pos.set_filename("unknown-file");
     401           1 :         expected3.f_pos.set_function("unknown-func");
     402           1 :         expected3.f_message = "The type of an element in the database has to be a string.";
     403           1 :         tc.f_expected.push_back(expected3);
     404             : 
     405           2 :         as2js::Database::Element::pointer_t db_element(new as2js::Database::Element("this.is.a.bad.element.name", element));
     406           1 :         tc.got_called();
     407             : 
     408           1 :         CPPUNIT_ASSERT(db_element->get_element_name() == "this.is.a.bad.element.name");
     409           1 :         CPPUNIT_ASSERT(db_element->get_type() == "");
     410           1 :         CPPUNIT_ASSERT(db_element->get_filename() == "");
     411           2 :         CPPUNIT_ASSERT(db_element->get_line() == 1);
     412             :     }
     413           1 : }
     414             : 
     415             : 
     416           1 : void As2JsDBUnitTests::test_package()
     417             : {
     418         101 :     for(size_t idx(0); idx < 100; ++idx)
     419             :     {
     420         100 :         as2js::Position pos;
     421             : 
     422             :         // one package of 10 elements
     423         200 :         as2js::JSON::JSONValue::object_t package_obj;
     424             : 
     425        7000 :         struct data_t
     426             :         {
     427             :             as2js::String   f_element_name;
     428             :             as2js::String   f_type;
     429             :             as2js::String   f_filename;
     430             :             int32_t         f_line;
     431             :         };
     432         200 :         std::vector<data_t> elements;
     433             : 
     434        1100 :         for(size_t j(0); j < 10; ++j)
     435             :         {
     436        1000 :             data_t data;
     437             : 
     438        1000 :             generate_string(data.f_type);
     439        2000 :             as2js::JSON::JSONValue::pointer_t type(new as2js::JSON::JSONValue(pos, data.f_type));
     440             : 
     441        1000 :             generate_string(data.f_filename);
     442        2000 :             as2js::JSON::JSONValue::pointer_t filename(new as2js::JSON::JSONValue(pos, data.f_filename));
     443             : 
     444             :             // generate a line number
     445        1000 :             data.f_line = (rand() & 0xFFFFFF) + 1;
     446        1000 :             as2js::Int64 line_int64(data.f_line);
     447        2000 :             as2js::JSON::JSONValue::pointer_t line(new as2js::JSON::JSONValue(pos, line_int64));
     448             : 
     449        2000 :             as2js::JSON::JSONValue::object_t obj;
     450        1000 :             obj["type"] = type;
     451        1000 :             obj["filename"] = filename;
     452        1000 :             obj["line"] = line;
     453        2000 :             as2js::JSON::JSONValue::pointer_t element(new as2js::JSON::JSONValue(pos, obj));
     454             : 
     455        1000 :             generate_string(data.f_element_name);
     456        1000 :             package_obj[data.f_element_name] = element;
     457             : 
     458        1000 :             elements.push_back(data);
     459             : 
     460             :             // as we're here, make sure we can create such a db element
     461        2000 :             as2js::Database::Element::pointer_t db_element(new as2js::Database::Element(data.f_element_name, element));
     462             : 
     463        1000 :             CPPUNIT_ASSERT(db_element->get_element_name() == data.f_element_name);
     464        1000 :             CPPUNIT_ASSERT(db_element->get_type() == data.f_type);
     465        1000 :             CPPUNIT_ASSERT(db_element->get_filename() == data.f_filename);
     466        1000 :             CPPUNIT_ASSERT(db_element->get_line() == data.f_line);
     467        1000 :         }
     468             : 
     469         200 :         as2js::JSON::JSONValue::pointer_t package(new as2js::JSON::JSONValue(pos, package_obj));
     470         200 :         as2js::String package_name;
     471         100 :         generate_string(package_name);
     472         200 :         as2js::Database::Package::pointer_t db_package(new as2js::Database::Package(package_name, package));
     473             : 
     474         100 :         CPPUNIT_ASSERT(db_package->get_package_name() == package_name);
     475             : 
     476        1100 :         for(size_t j(0); j < 10; ++j)
     477             :         {
     478        1000 :             as2js::Database::Element::pointer_t e(db_package->get_element(elements[j].f_element_name));
     479             : 
     480        1000 :             CPPUNIT_ASSERT(e->get_element_name() == elements[j].f_element_name);
     481        1000 :             CPPUNIT_ASSERT(e->get_type()         == elements[j].f_type);
     482        1000 :             CPPUNIT_ASSERT(e->get_filename()     == elements[j].f_filename);
     483        1000 :             CPPUNIT_ASSERT(e->get_line()         == elements[j].f_line);
     484             : 
     485             :             // the add_element() does nothing if we add an element with the
     486             :             // same name
     487        2000 :             as2js::Database::Element::pointer_t n(db_package->add_element(elements[j].f_element_name));
     488        1000 :             CPPUNIT_ASSERT(n == e);
     489        1000 :         }
     490             : 
     491             :         // attempts a find as well
     492        1100 :         for(size_t j(0); j < 10; ++j)
     493             :         {
     494             :             {
     495             :                 // pattern "starts with"
     496        1000 :                 int len(rand() % 5 + 1);
     497        1000 :                 as2js::String pattern(elements[j].f_element_name.substr(0, len));
     498        1000 :                 pattern += '*';
     499        2000 :                 as2js::Database::element_vector_t list(db_package->find_elements(pattern));
     500             : 
     501             :                 // check that the name of the elements found this way are valid
     502             :                 // matches
     503        1000 :                 size_t const max_elements(list.size());
     504        1000 :                 CPPUNIT_ASSERT(max_elements >= 1);
     505        2013 :                 for(size_t k(0); k < max_elements; ++k)
     506             :                 {
     507        1013 :                     as2js::String name(list[k]->get_element_name());
     508        2026 :                     as2js::String match(name.substr(0, len));
     509        1013 :                     match += '*';
     510        1013 :                     CPPUNIT_ASSERT(pattern == match);
     511        1013 :                 }
     512             : 
     513             :                 // now verify that we found them all
     514       11000 :                 for(size_t q(0); q < 10; ++q)
     515             :                 {
     516       10000 :                     as2js::String name(elements[q].f_element_name);
     517       20000 :                     as2js::String start_with(name.substr(0, len));
     518       10000 :                     start_with += '*';
     519       10000 :                     if(start_with == pattern)
     520             :                     {
     521             :                         // find that entry in the list
     522        1013 :                         bool good(false);
     523        1028 :                         for(size_t k(0); k < max_elements; ++k)
     524             :                         {
     525        1028 :                             if(list[k]->get_element_name() == name)
     526             :                             {
     527        1013 :                                 good = true;
     528        1013 :                                 break;
     529             :                             }
     530             :                         }
     531        1013 :                         CPPUNIT_ASSERT(good);
     532             :                     }
     533       11000 :                 }
     534             :             }
     535             : 
     536             :             {
     537             :                 // pattern "ends with"
     538        1000 :                 int len(rand() % 5 + 1);
     539        1000 :                 as2js::String pattern;
     540        1000 :                 pattern += '*';
     541        1000 :                 pattern += elements[j].f_element_name.substr(elements[j].f_element_name.length() - len, len);
     542        2000 :                 as2js::Database::element_vector_t list(db_package->find_elements(pattern));
     543             : 
     544             :                 // check that the name of the elements found this way are valid
     545             :                 // matches
     546        1000 :                 size_t const max_elements(list.size());
     547        1000 :                 CPPUNIT_ASSERT(max_elements >= 1);
     548        2009 :                 for(size_t k(0); k < max_elements; ++k)
     549             :                 {
     550        1009 :                     as2js::String name(list[k]->get_element_name());
     551        2018 :                     as2js::String match;
     552        1009 :                     match += '*';
     553        1009 :                     match += name.substr(name.length() - len, len);
     554        1009 :                     CPPUNIT_ASSERT(pattern == match);
     555        1009 :                 }
     556             : 
     557             :                 // now verify that we found them all
     558       11000 :                 for(size_t q(0); q < 10; ++q)
     559             :                 {
     560       10000 :                     as2js::String name(elements[q].f_element_name);
     561       20000 :                     as2js::String end_with;
     562       10000 :                     end_with += '*';
     563       10000 :                     end_with += name.substr(name.length() - len, len);
     564       10000 :                     if(end_with == pattern)
     565             :                     {
     566             :                         // find that entry in the list
     567        1009 :                         bool good(false);
     568        1018 :                         for(size_t k(0); k < max_elements; ++k)
     569             :                         {
     570        1018 :                             if(list[k]->get_element_name() == name)
     571             :                             {
     572        1009 :                                 good = true;
     573        1009 :                                 break;
     574             :                             }
     575             :                         }
     576        1009 :                         CPPUNIT_ASSERT(good);
     577             :                     }
     578       11000 :                 }
     579             :             }
     580             : 
     581             :             {
     582             :                 // pattern "starts/ends with"
     583             :                 // names are generated by the generate_string() so they are
     584             :                 // at least 20 characters long which is enough here
     585        1000 :                 int slen(rand() % 5 + 1);
     586        1000 :                 int elen(rand() % 5 + 1);
     587        1000 :                 as2js::String pattern;
     588        1000 :                 pattern += elements[j].f_element_name.substr(0, slen);
     589        1000 :                 pattern += '*';
     590        1000 :                 pattern += elements[j].f_element_name.substr(elements[j].f_element_name.length() - elen, elen);
     591        2000 :                 as2js::Database::element_vector_t list(db_package->find_elements(pattern));
     592             : 
     593             :                 // check that the name of the elements found this way are valid
     594             :                 // matches
     595        1000 :                 size_t const max_elements(list.size());
     596        1000 :                 CPPUNIT_ASSERT(max_elements >= 1);
     597        2000 :                 for(size_t k(0); k < max_elements; ++k)
     598             :                 {
     599        1000 :                     as2js::String name(list[k]->get_element_name());
     600        2000 :                     as2js::String match;
     601        1000 :                     match += name.substr(0, slen);
     602        1000 :                     match += '*';
     603        1000 :                     match += name.substr(name.length() - elen, elen);
     604        1000 :                     CPPUNIT_ASSERT(pattern == match);
     605        1000 :                 }
     606             : 
     607             :                 // now verify that we found them all
     608       11000 :                 for(size_t q(0); q < 10; ++q)
     609             :                 {
     610       10000 :                     as2js::String name(elements[q].f_element_name);
     611       20000 :                     as2js::String end_with;
     612       10000 :                     end_with += name.substr(0, slen);
     613       10000 :                     end_with += '*';
     614       10000 :                     end_with += name.substr(name.length() - elen, elen);
     615       10000 :                     if(end_with == pattern)
     616             :                     {
     617             :                         // find that entry in the list
     618        1000 :                         bool good(false);
     619        1000 :                         for(size_t k(0); k < max_elements; ++k)
     620             :                         {
     621        1000 :                             if(list[k]->get_element_name() == name)
     622             :                             {
     623        1000 :                                 good = true;
     624        1000 :                                 break;
     625             :                             }
     626             :                         }
     627        1000 :                         CPPUNIT_ASSERT(good);
     628             :                     }
     629       11000 :                 }
     630             :             }
     631             :         }
     632             : 
     633             :         // add a few more elements
     634        1100 :         for(size_t j(0); j < 10; ++j)
     635             :         {
     636             :             // at this point the name of an element is not verified because
     637             :             // all the internal code expects valid identifiers for those
     638             :             // names so any random name will do in this test
     639        1000 :             as2js::String name;
     640        1000 :             generate_string(name);
     641        2000 :             as2js::Database::Element::pointer_t e(db_package->add_element(name));
     642             : 
     643             :             // it creates an empty element in this case
     644        1000 :             CPPUNIT_ASSERT(e->get_element_name() == name);
     645        1000 :             CPPUNIT_ASSERT(e->get_type() == "");
     646        1000 :             CPPUNIT_ASSERT(e->get_filename() == "");
     647        1000 :             CPPUNIT_ASSERT(e->get_line() == 1);
     648        1000 :         }
     649         100 :     }
     650             : 
     651             :     // now check for erroneous data
     652             :     {
     653           1 :         as2js::Position pos;
     654             : 
     655           2 :         as2js::String not_obj;
     656           1 :         generate_string(not_obj);
     657           2 :         as2js::JSON::JSONValue::pointer_t bad_package(new as2js::JSON::JSONValue(pos, not_obj));
     658             : 
     659           2 :         CPPUNIT_ASSERT_THROW(new as2js::Database::Package("expect.a.throw", bad_package), as2js::exception_internal_error);
     660             :     }
     661             : 
     662             :     {
     663           1 :         as2js::Position pos;
     664             : 
     665           1 :         int32_t bad_int((rand() & 0xFFFFFF) + 1);
     666           1 :         as2js::Int64 bad_int64(bad_int);
     667           2 :         as2js::JSON::JSONValue::pointer_t bad_a(new as2js::JSON::JSONValue(pos, bad_int64));
     668             : 
     669           1 :         double bad_float(static_cast<double>((rand() << 16) ^ rand()) / static_cast<double>((rand() << 16) ^ rand()));
     670           1 :         as2js::Float64 bad_float64(bad_float);
     671           2 :         as2js::JSON::JSONValue::pointer_t bad_b(new as2js::JSON::JSONValue(pos, bad_float64));
     672             : 
     673           2 :         as2js::String bad_string;
     674           1 :         generate_string(bad_string);
     675           2 :         as2js::JSON::JSONValue::pointer_t bad_c(new as2js::JSON::JSONValue(pos, bad_string));
     676             : 
     677             :         //as2js::JSON::JSONValue::object_t bad_obj;
     678             :         //as2js::String n1;
     679             :         //generate_string(n1);
     680             :         //bad_obj[n1] = bad_a;
     681             :         //as2js::String n2;
     682             :         //generate_string(n2);
     683             :         //bad_obj[n2] = bad_b;
     684             :         //as2js::String n3;
     685             :         //generate_string(n3);
     686             :         //bad_obj[n3] = bad_c;
     687             :         //as2js::JSON::JSONValue::pointer_t element(new as2js::JSON::JSONValue(pos, bad_obj));
     688             : 
     689           2 :         as2js::JSON::JSONValue::object_t package_obj;
     690           2 :         as2js::String e1_name;
     691           1 :         generate_string(e1_name);
     692           1 :         package_obj[e1_name] = bad_a;
     693             : 
     694           2 :         as2js::String e2_name;
     695           1 :         generate_string(e2_name);
     696           1 :         package_obj[e2_name] = bad_b;
     697             : 
     698           2 :         as2js::String e3_name;
     699           1 :         generate_string(e3_name);
     700           1 :         package_obj[e3_name] = bad_c;
     701             : 
     702             :         // WARNING: errors should be generated in the order the elements
     703             :         //          appear in the map
     704           2 :         test_callback tc;
     705             : 
     706           2 :         test_callback::expected_t expected1;
     707           1 :         expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     708           1 :         expected1.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     709           1 :         expected1.f_pos.set_filename("unknown-file");
     710           1 :         expected1.f_pos.set_function("unknown-func");
     711           1 :         expected1.f_message = "A database is expected to be an object of object packages composed of object elements.";
     712           1 :         tc.f_expected.push_back(expected1);
     713             : 
     714           2 :         test_callback::expected_t expected2;
     715           1 :         expected2.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     716           1 :         expected2.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     717           1 :         expected2.f_pos.set_filename("unknown-file");
     718           1 :         expected2.f_pos.set_function("unknown-func");
     719           1 :         expected2.f_message = "A database is expected to be an object of object packages composed of object elements.";
     720           1 :         tc.f_expected.push_back(expected2);
     721             : 
     722           2 :         test_callback::expected_t expected3;
     723           1 :         expected3.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     724           1 :         expected3.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     725           1 :         expected3.f_pos.set_filename("unknown-file");
     726           1 :         expected3.f_pos.set_function("unknown-func");
     727           1 :         expected3.f_message = "A database is expected to be an object of object packages composed of object elements.";
     728           1 :         tc.f_expected.push_back(expected3);
     729             : 
     730           2 :         as2js::JSON::JSONValue::pointer_t package(new as2js::JSON::JSONValue(pos, package_obj));
     731             : 
     732           2 :         as2js::String package_name;
     733           1 :         generate_string(package_name);
     734           2 :         as2js::Database::Package::pointer_t db_package(new as2js::Database::Package(package_name, package));
     735           1 :         tc.got_called();
     736           2 :         CPPUNIT_ASSERT(!!db_package);
     737             :     }
     738           1 : }
     739             : 
     740             : 
     741           1 : void As2JsDBUnitTests::test_database()
     742             : {
     743           1 :     as2js::Database::pointer_t db(new as2js::Database);
     744             : 
     745             :     // saving without a load does nothing
     746           1 :     db->save();
     747             : 
     748             :     // whatever the package name, it does not exist...
     749           1 :     CPPUNIT_ASSERT(!db->get_package("name"));
     750             : 
     751             :     // adding a package fails with a throw
     752           1 :     CPPUNIT_ASSERT_THROW(db->add_package("name"), as2js::exception_internal_error);
     753             : 
     754             :     // the find_packages() function returns nothing
     755           2 :     as2js::Database::package_vector_t v(db->find_packages("name"));
     756           1 :     CPPUNIT_ASSERT(v.empty());
     757             : 
     758             :     // now test a load()
     759           1 :     CPPUNIT_ASSERT(db->load("test.db"));
     760             : 
     761             :     // a second time returns true also
     762           1 :     CPPUNIT_ASSERT(db->load("test.db"));
     763             : 
     764           2 :     as2js::Database::Package::pointer_t p1(db->add_package("p1"));
     765           2 :     as2js::Database::Element::pointer_t e1(p1->add_element("e1"));
     766           1 :     e1->set_type("type-e1");
     767           1 :     e1->set_filename("e1.as");
     768           1 :     e1->set_line(33);
     769           2 :     as2js::Database::Element::pointer_t e2(p1->add_element("e2"));
     770           1 :     e2->set_type("type-e2");
     771           1 :     e2->set_filename("e2.as");
     772           1 :     e2->set_line(66);
     773           2 :     as2js::Database::Element::pointer_t e3(p1->add_element("e3"));
     774           1 :     e3->set_type("type-e3");
     775           1 :     e3->set_filename("e3.as");
     776           1 :     e3->set_line(99);
     777             : 
     778           2 :     as2js::Database::Package::pointer_t p2(db->add_package("p2"));
     779           2 :     as2js::Database::Element::pointer_t e4(p2->add_element("e4"));
     780           1 :     e4->set_type("type-e4");
     781           1 :     e4->set_filename("e4.as");
     782           1 :     e4->set_line(44);
     783           2 :     as2js::Database::Element::pointer_t e5(p2->add_element("e5"));
     784           1 :     e5->set_type("type-e5");
     785           1 :     e5->set_filename("e5.as");
     786           1 :     e5->set_line(88);
     787           2 :     as2js::Database::Element::pointer_t e6(p2->add_element("e6"));
     788           1 :     e6->set_type("type-e6");
     789           1 :     e6->set_filename("e6.as");
     790           1 :     e6->set_line(11);
     791             : 
     792           1 :     db->save();
     793             : 
     794           1 :     CPPUNIT_ASSERT(db->get_package("p1") == p1);
     795           1 :     CPPUNIT_ASSERT(db->get_package("p2") == p2);
     796             : 
     797           2 :     as2js::Database::Package::pointer_t q(db->get_package("p1"));
     798           1 :     CPPUNIT_ASSERT(q == p1);
     799           2 :     as2js::Database::Package::pointer_t r(db->get_package("p2"));
     800           1 :     CPPUNIT_ASSERT(r == p2);
     801             : 
     802           2 :     as2js::Database::pointer_t qdb(new as2js::Database);
     803           1 :     CPPUNIT_ASSERT(qdb->load("test.db"));
     804             : 
     805           2 :     as2js::Database::Package::pointer_t np1(qdb->get_package("p1"));
     806           2 :     as2js::Database::Element::pointer_t ne1(np1->get_element("e1"));
     807           1 :     CPPUNIT_ASSERT(ne1->get_type() == "type-e1");
     808           1 :     CPPUNIT_ASSERT(ne1->get_filename() == "e1.as");
     809           1 :     CPPUNIT_ASSERT(ne1->get_line() == 33);
     810           2 :     as2js::Database::Element::pointer_t ne2(np1->get_element("e2"));
     811           1 :     CPPUNIT_ASSERT(ne2->get_type() == "type-e2");
     812           1 :     CPPUNIT_ASSERT(ne2->get_filename() == "e2.as");
     813           1 :     CPPUNIT_ASSERT(ne2->get_line() == 66);
     814           2 :     as2js::Database::Element::pointer_t ne3(np1->get_element("e3"));
     815           1 :     CPPUNIT_ASSERT(ne3->get_type() == "type-e3");
     816           1 :     CPPUNIT_ASSERT(ne3->get_filename() == "e3.as");
     817           1 :     CPPUNIT_ASSERT(ne3->get_line() == 99);
     818           2 :     as2js::Database::Package::pointer_t np2(qdb->get_package("p2"));
     819           2 :     as2js::Database::Element::pointer_t ne4(np2->get_element("e4"));
     820           1 :     CPPUNIT_ASSERT(ne4->get_type() == "type-e4");
     821           1 :     CPPUNIT_ASSERT(ne4->get_filename() == "e4.as");
     822           1 :     CPPUNIT_ASSERT(ne4->get_line() == 44);
     823           2 :     as2js::Database::Element::pointer_t ne5(np2->get_element("e5"));
     824           1 :     CPPUNIT_ASSERT(ne5->get_type() == "type-e5");
     825           1 :     CPPUNIT_ASSERT(ne5->get_filename() == "e5.as");
     826           1 :     CPPUNIT_ASSERT(ne5->get_line() == 88);
     827           2 :     as2js::Database::Element::pointer_t ne6(np2->get_element("e6"));
     828           1 :     CPPUNIT_ASSERT(ne6->get_type() == "type-e6");
     829           1 :     CPPUNIT_ASSERT(ne6->get_filename() == "e6.as");
     830           1 :     CPPUNIT_ASSERT(ne6->get_line() == 11);
     831             : 
     832           2 :     as2js::Database::package_vector_t np1a(qdb->find_packages("p1"));
     833           1 :     CPPUNIT_ASSERT(np1a.size() == 1);
     834           1 :     CPPUNIT_ASSERT(np1a[0] == np1);
     835           2 :     as2js::Database::package_vector_t np2a(qdb->find_packages("p2"));
     836           1 :     CPPUNIT_ASSERT(np2a.size() == 1);
     837           1 :     CPPUNIT_ASSERT(np2a[0] == np2);
     838           2 :     as2js::Database::package_vector_t np3a(qdb->find_packages("p*"));
     839           1 :     CPPUNIT_ASSERT(np3a.size() == 2);
     840           1 :     CPPUNIT_ASSERT(np3a[0] == np1);
     841           1 :     CPPUNIT_ASSERT(np3a[1] == np2);
     842             : 
     843             :     // done with that one
     844           1 :     unlink("test.db");
     845             : 
     846             :     {
     847             :         {
     848           1 :             std::ofstream db_file;
     849           1 :             db_file.open("t1.db");
     850           1 :             CPPUNIT_ASSERT(db_file.is_open());
     851           1 :             db_file << "// db file\n"
     852           1 :                     << "an invalid file\n";
     853             :         }
     854             : 
     855           1 :         as2js::Database::pointer_t pdb(new as2js::Database);
     856           1 :         CPPUNIT_ASSERT(!pdb->load("t1.db"));
     857             :         // make sure we can still create a package (because here f_value
     858             :         // is null)
     859           2 :         as2js::Database::Package::pointer_t tp(pdb->add_package("another"));
     860           1 :         CPPUNIT_ASSERT(!!tp);
     861             : 
     862           2 :         unlink("t1.db");
     863             :     }
     864             : 
     865             :     {
     866             :         {
     867           1 :             std::ofstream db_file;
     868           1 :             db_file.open("t2.db");
     869           1 :             CPPUNIT_ASSERT(db_file.is_open());
     870           1 :             db_file << "// db file\n"
     871           1 :                     << "null\n";
     872             :         }
     873             : 
     874           1 :         as2js::Database::pointer_t pdb(new as2js::Database);
     875           1 :         CPPUNIT_ASSERT(pdb->load("t2.db"));
     876           2 :         as2js::Database::package_vector_t np(pdb->find_packages("*"));
     877           1 :         CPPUNIT_ASSERT(np.empty());
     878             : 
     879           2 :         unlink("t2.db");
     880             :     }
     881             : 
     882             :     {
     883             :         {
     884           1 :             std::ofstream db_file;
     885           1 :             db_file.open("t3.db");
     886           1 :             CPPUNIT_ASSERT(db_file.is_open());
     887           1 :             db_file << "// db file\n"
     888           1 :                     << "\"unexpected string\"\n";
     889             :         }
     890             : 
     891           1 :         test_callback tc;
     892             : 
     893           2 :         test_callback::expected_t expected1;
     894           1 :         expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     895           1 :         expected1.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     896           1 :         expected1.f_pos.set_filename("t3.db");
     897           1 :         expected1.f_pos.set_function("unknown-func");
     898           1 :         expected1.f_message = "A database must be defined as a JSON object, or set to 'null'.";
     899           1 :         tc.f_expected.push_back(expected1);
     900             : 
     901           2 :         as2js::Database::pointer_t sdb(new as2js::Database);
     902           1 :         CPPUNIT_ASSERT(!sdb->load("t3.db"));
     903           1 :         tc.got_called();
     904             : 
     905           2 :         as2js::Database::package_vector_t np(sdb->find_packages("*"));
     906           1 :         CPPUNIT_ASSERT(np.empty());
     907             : 
     908           2 :         unlink("t3.db");
     909             :     }
     910             : 
     911             :     {
     912             :         {
     913           1 :             std::ofstream db_file;
     914           1 :             db_file.open("t4.db");
     915           1 :             CPPUNIT_ASSERT(db_file.is_open());
     916           1 :             db_file << "// db file\n"
     917           1 :                     << "{\"invalid\":\"object-here\"}\n";
     918             :         }
     919             : 
     920           1 :         test_callback tc;
     921             : 
     922           2 :         test_callback::expected_t expected1;
     923           1 :         expected1.f_message_level = as2js::message_level_t::MESSAGE_LEVEL_ERROR;
     924           1 :         expected1.f_error_code = as2js::err_code_t::AS_ERR_UNEXPECTED_DATABASE;
     925           1 :         expected1.f_pos.set_filename("t4.db");
     926           1 :         expected1.f_pos.set_function("unknown-func");
     927           1 :         expected1.f_message = "A database is expected to be an object of object packages composed of elements.";
     928           1 :         tc.f_expected.push_back(expected1);
     929             : 
     930           2 :         as2js::Database::pointer_t sdb(new as2js::Database);
     931           1 :         CPPUNIT_ASSERT(!sdb->load("t4.db"));
     932           1 :         tc.got_called();
     933             : 
     934           2 :         as2js::Database::package_vector_t np(sdb->find_packages("*"));
     935           1 :         CPPUNIT_ASSERT(np.empty());
     936             : 
     937           2 :         unlink("t4.db");
     938           1 :     }
     939          13 : }
     940             : 
     941             : 
     942             : 
     943             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.10