Blame unit-tests/ArrayTest.cc

Packit a4aae4
// -*- mode: c++; c-basic-offset:4 -*-
Packit a4aae4
Packit a4aae4
// This file is part of libdap, A C++ implementation of the OPeNDAP Data
Packit a4aae4
// Access Protocol.
Packit a4aae4
Packit a4aae4
// Copyright (c) 2005 OPeNDAP, Inc.
Packit a4aae4
// Author: James Gallagher <jgallagher@opendap.org>
Packit a4aae4
//
Packit a4aae4
// This library is free software; you can redistribute it and/or
Packit a4aae4
// modify it under the terms of the GNU Lesser General Public
Packit a4aae4
// License as published by the Free Software Foundation; either
Packit a4aae4
// version 2.1 of the License, or (at your option) any later version.
Packit a4aae4
// 
Packit a4aae4
// This library is distributed in the hope that it will be useful,
Packit a4aae4
// but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a4aae4
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a4aae4
// Lesser General Public License for more details.
Packit a4aae4
// 
Packit a4aae4
// You should have received a copy of the GNU Lesser General Public
Packit a4aae4
// License along with this library; if not, write to the Free Software
Packit a4aae4
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit a4aae4
//
Packit a4aae4
// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
Packit a4aae4
Packit a4aae4
#include <cppunit/TextTestRunner.h>
Packit a4aae4
#include <cppunit/extensions/TestFactoryRegistry.h>
Packit a4aae4
#include <cppunit/extensions/HelperMacros.h>
Packit a4aae4
Packit a4aae4
#include <cstring>
Packit a4aae4
#include <string>
Packit a4aae4
Packit a4aae4
#include "GNURegex.h"
Packit a4aae4
Packit a4aae4
#include "Array.h"
Packit a4aae4
#include "Int16.h"
Packit a4aae4
#include "Str.h"
Packit a4aae4
#include "Structure.h"
Packit a4aae4
Packit a4aae4
#include "debug.h"
Packit a4aae4
#include "GetOpt.h"
Packit a4aae4
Packit a4aae4
using namespace CppUnit;
Packit a4aae4
using namespace std;
Packit a4aae4
Packit a4aae4
static bool debug = false;
Packit a4aae4
Packit a4aae4
namespace libdap {
Packit a4aae4
Packit a4aae4
class ArrayTest: public TestFixture {
Packit a4aae4
private:
Packit a4aae4
    Array *d_cardinal, *d_string, *d_structure;
Packit a4aae4
    Int16 *d_int16;
Packit a4aae4
    Str *d_str;
Packit a4aae4
    Structure *d_struct;
Packit a4aae4
Packit a4aae4
    string svalues[4];
Packit a4aae4
public:
Packit a4aae4
    ArrayTest()
Packit a4aae4
    {
Packit a4aae4
        svalues[0] = "0 String";
Packit a4aae4
        svalues[1] = "1 String";
Packit a4aae4
        svalues[2] = "2 String";
Packit a4aae4
        svalues[3] = "3 String";
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    ~ArrayTest()
Packit a4aae4
    {
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void setUp()
Packit a4aae4
    {
Packit a4aae4
        d_int16 = new Int16("Int16");
Packit a4aae4
        DBG(cerr << "d_int16: " << d_int16 << endl);
Packit a4aae4
        d_cardinal = new Array("Array_of_Int16", d_int16);
Packit a4aae4
        d_cardinal->append_dim(4, "dimension");
Packit a4aae4
        dods_int16 buffer[4] = { 0, 1, 2, 3 };
Packit a4aae4
        d_cardinal->val2buf(buffer);
Packit a4aae4
#ifdef DODS_DEBUG
Packit a4aae4
        for (int i = 0; i < 4; ++i)
Packit a4aae4
        cerr << "buffer[" << i << "]: " << buffer[i] << endl;
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
        d_str = new Str("Str");
Packit a4aae4
        d_string = new Array("Array_of_String", d_str);
Packit a4aae4
        d_string->append_dim(4, "dimension");
Packit a4aae4
        string sbuffer[4] = { "0 String", "1 String", "2 String", "3 String" };
Packit a4aae4
        d_string->val2buf(sbuffer);
Packit a4aae4
#ifdef DODS_DEBUG
Packit a4aae4
        for (int i = 0; i < 4; ++i)
Packit a4aae4
        cerr << "sbuffer[" << i << "]: " << sbuffer[i] << endl;
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
        d_struct = new Structure("Structure");
Packit a4aae4
        d_struct->add_var(d_int16);
Packit a4aae4
        d_structure = new Array("Array_of_Strctures", d_struct);
Packit a4aae4
        d_structure->append_dim(4, "dimension");
Packit a4aae4
        ostringstream oss;
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            oss.str("");
Packit a4aae4
            oss << "field" << i;
Packit a4aae4
            Int16 *n = new Int16(oss.str());
Packit a4aae4
            DBG(cerr << "n " << i << ": " << n << endl);
Packit a4aae4
            oss.str("");
Packit a4aae4
            oss << "element" << i;
Packit a4aae4
            Structure *s = new Structure(oss.str());
Packit a4aae4
            s->add_var(n);
Packit a4aae4
            d_structure->set_vec(i, s);
Packit a4aae4
            delete n;
Packit a4aae4
            n = 0;
Packit a4aae4
            delete s;
Packit a4aae4
            s = 0;
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
        delete d_int16;
Packit a4aae4
        d_int16 = 0;
Packit a4aae4
        delete d_str;
Packit a4aae4
        d_str = 0;
Packit a4aae4
        delete d_struct;
Packit a4aae4
        d_struct = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void tearDown()
Packit a4aae4
    {
Packit a4aae4
        delete d_cardinal;
Packit a4aae4
        delete d_string;
Packit a4aae4
        delete d_structure;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    bool re_match(Regex &r, const char *s)
Packit a4aae4
    {
Packit a4aae4
        int match_position = r.match(s, strlen(s));
Packit a4aae4
        DBG(cerr << "match position: " << match_position
Packit a4aae4
            << " string length: " << (int)strlen(s) << endl);
Packit a4aae4
        return match_position == (int) strlen(s);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE (ArrayTest);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (duplicate_cardinal_test);
Packit a4aae4
    CPPUNIT_TEST (duplicate_string_test);
Packit a4aae4
    CPPUNIT_TEST (duplicate_structure_test);
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE_END();
Packit a4aae4
Packit a4aae4
    void duplicate_structure_test()
Packit a4aae4
    {
Packit a4aae4
        Array::Dim_iter i = d_structure->dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(d_structure->dimension_size(i) == 4);
Packit a4aae4
#ifdef DODS_DEBUG
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            Structure *s = dynamic_cast<Structure*>(d_structure->var(i));
Packit a4aae4
            DBG(cerr << "s: " << s << endl);
Packit a4aae4
            if (s)
Packit a4aae4
            s->print_decl(cerr);
Packit a4aae4
        }
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
        Array *a = new Array(*d_structure);
Packit a4aae4
        // a = *d_structure; I test operator= in duplicate_cardinal_test().
Packit a4aae4
        i = a->dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(a->dimension_size(i) == 4);
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            // The point of this test is to ensure that the const ctor
Packit a4aae4
            // performs a deep copy; first test to make sure the pointers
Packit a4aae4
            // to BaseType instnaces are different in the two objects.
Packit a4aae4
            Structure *src = dynamic_cast<Structure*>(d_structure->var(i));
Packit a4aae4
            Structure *dest = dynamic_cast<Structure*>(a->var(i));
Packit a4aae4
            CPPUNIT_ASSERT(src != dest);
Packit a4aae4
Packit a4aae4
            // However, for the deep copy to be correct, the two arrays must
Packit a4aae4
            // have equivalent elements. We know there's only one field...
Packit a4aae4
            CPPUNIT_ASSERT(src->type() == dods_structure_c && dest->type() == dods_structure_c);
Packit a4aae4
            Constructor::Vars_iter s = src->var_begin();
Packit a4aae4
            Constructor::Vars_iter d = dest->var_begin();
Packit a4aae4
            CPPUNIT_ASSERT((*s)->type() == dods_int16_c && (*d)->type() == dods_int16_c);
Packit a4aae4
            CPPUNIT_ASSERT((*s)->name() == (*d)->name());
Packit a4aae4
        }
Packit a4aae4
        delete a;
Packit a4aae4
        a = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void duplicate_string_test()
Packit a4aae4
    {
Packit a4aae4
        Array::Dim_iter i = d_string->dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(d_string->dimension_size(i) == 4);
Packit a4aae4
        string *s = new string[4];
Packit a4aae4
        d_string->buf2val((void**) &s);
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            CPPUNIT_ASSERT(s[i] == svalues[i]);
Packit a4aae4
            DBG(cerr << "s[" << i << "]: " << s[i] << endl);
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
        Array a = *d_string;
Packit a4aae4
        i = a.dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(a.dimension_size(i) == 4);
Packit a4aae4
Packit a4aae4
        string *s2 = new string[4];
Packit a4aae4
        d_string->buf2val((void**) &s2;;
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            CPPUNIT_ASSERT(s2[i] == svalues[i]);
Packit a4aae4
            DBG(cerr << "s2[" << i << "]: " << s2[i] << endl);
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
        delete[] s;
Packit a4aae4
        s = 0;
Packit a4aae4
        delete[] s2;
Packit a4aae4
        s2 = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void duplicate_cardinal_test()
Packit a4aae4
    {
Packit a4aae4
        Array::Dim_iter i = d_cardinal->dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(d_cardinal->dimension_size(i) == 4);
Packit a4aae4
        dods_int16 *b = new dods_int16[4];
Packit a4aae4
        d_cardinal->buf2val((void**) &b);
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            CPPUNIT_ASSERT(b[i] == i);
Packit a4aae4
            DBG(cerr << "b[" << i << "]: " << b[i] << endl);
Packit a4aae4
        }
Packit a4aae4
        delete[] b;
Packit a4aae4
        b = 0;
Packit a4aae4
Packit a4aae4
        Array a = *d_cardinal;
Packit a4aae4
        i = a.dim_begin();
Packit a4aae4
        CPPUNIT_ASSERT(a.dimension_size(i) == 4);
Packit a4aae4
Packit a4aae4
        dods_int16 *b2 = new dods_int16[4];
Packit a4aae4
        d_cardinal->buf2val((void**) &b2;;
Packit a4aae4
        for (int i = 0; i < 4; ++i) {
Packit a4aae4
            CPPUNIT_ASSERT(b2[i] == i);
Packit a4aae4
            DBG(cerr << "b2[" << i << "]: " << b2[i] << endl);
Packit a4aae4
        }
Packit a4aae4
        delete[] b2;
Packit a4aae4
        b2 = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
};
Packit a4aae4
Packit a4aae4
CPPUNIT_TEST_SUITE_REGISTRATION (ArrayTest);
Packit a4aae4
Packit a4aae4
} // namespace libdap
Packit a4aae4
Packit a4aae4
int main(int argc, char *argv[])
Packit a4aae4
{
Packit a4aae4
    GetOpt getopt(argc, argv, "dh");
Packit a4aae4
    int option_char;
Packit a4aae4
Packit a4aae4
    while ((option_char = getopt()) != -1)
Packit a4aae4
        switch (option_char) {
Packit a4aae4
        case 'd':
Packit a4aae4
            debug = 1;  // debug is a static global
Packit a4aae4
            break;
Packit a4aae4
Packit a4aae4
        case 'h': {     // help - show test names
Packit a4aae4
            cerr << "Usage: ArrayTest has the following tests:" << endl;
Packit a4aae4
            const std::vector<Test*> &tests = libdap::ArrayTest::suite()->getTests();
Packit a4aae4
            unsigned int prefix_len = libdap::ArrayTest::suite()->getName().append("::").length();
Packit a4aae4
            for (std::vector<Test*>::const_iterator i = tests.begin(), e = tests.end(); i != e; ++i) {
Packit a4aae4
                cerr << (*i)->getName().replace(0, prefix_len, "") << endl;
Packit a4aae4
            }
Packit a4aae4
            break;
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
        default:
Packit a4aae4
            break;
Packit a4aae4
        }
Packit a4aae4
Packit a4aae4
    CppUnit::TextTestRunner runner;
Packit a4aae4
    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
Packit a4aae4
Packit a4aae4
    bool wasSuccessful = true;
Packit a4aae4
    string test = "";
Packit a4aae4
    int i = getopt.optind;
Packit a4aae4
    if (i == argc) {
Packit a4aae4
        // run them all
Packit a4aae4
        wasSuccessful = runner.run("");
Packit a4aae4
    }
Packit a4aae4
    else {
Packit a4aae4
        for (; i < argc; ++i) {
Packit a4aae4
            if (debug) cerr << "Running " << argv[i] << endl;
Packit a4aae4
            test = libdap::ArrayTest::suite()->getName().append("::").append(argv[i]);
Packit a4aae4
            wasSuccessful = wasSuccessful && runner.run(test);
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    return wasSuccessful ? 0 : 1;
Packit a4aae4
}