Blame unit-tests/AttrTableTest.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) 2002,2003 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 "config.h"
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
#include <sstream>
Packit a4aae4
Packit a4aae4
#if HAVE_UNISTD_H
Packit a4aae4
#include <unistd.h>
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
#include "GNURegex.h"
Packit a4aae4
#include "AttrTable.h"
Packit a4aae4
#include "debug.h"
Packit a4aae4
Packit a4aae4
#include "testFile.h"
Packit a4aae4
#include "GetOpt.h"
Packit a4aae4
Packit a4aae4
static bool debug = false;
Packit a4aae4
Packit a4aae4
#undef DBG
Packit a4aae4
#define DBG(x) do { if (debug) (x); } while(false);
Packit a4aae4
Packit a4aae4
using namespace CppUnit;
Packit a4aae4
using namespace std;
Packit a4aae4
using namespace libdap;
Packit a4aae4
Packit a4aae4
static string build_fqn(AttrTable *at, string fqn)
Packit a4aae4
{
Packit a4aae4
    // The strange behavior at the top level is because the top level of an
Packit a4aae4
    // AttrTable (i.e. the DAS) is anonymous. Another bad design... jhrg 2/8/06
Packit a4aae4
    if (!at || !at->get_parent() || at->get_name().empty())
Packit a4aae4
        return fqn;
Packit a4aae4
    else
Packit a4aae4
        return build_fqn(at->get_parent(), at->get_name() + string(".") + fqn);
Packit a4aae4
}
Packit a4aae4
Packit a4aae4
namespace libdap {
Packit a4aae4
Packit a4aae4
class AttrTableTest: public TestFixture {
Packit a4aae4
private:
Packit a4aae4
    AttrTable *at1;
Packit a4aae4
    AttrTable *cont_a, *cont_b, *cont_c, *cont_ba, *cont_ca, *cont_caa;
Packit a4aae4
Packit a4aae4
public:
Packit a4aae4
    AttrTableTest()
Packit a4aae4
    {
Packit a4aae4
    }
Packit a4aae4
    ~AttrTableTest()
Packit a4aae4
    {
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void setUp()
Packit a4aae4
    {
Packit a4aae4
        at1 = new AttrTable;
Packit a4aae4
        cont_a = at1->append_container("a");
Packit a4aae4
        cont_a->append_attr("size", "Int32", "7");
Packit a4aae4
        cont_a->append_attr("type", "String", "cars");
Packit a4aae4
Packit a4aae4
        cont_b = at1->append_container("b");
Packit a4aae4
        cont_b->append_attr("number", "Int32", "1");
Packit a4aae4
        cont_b->append_attr("type", "String", "houses");
Packit a4aae4
        cont_ba = cont_b->append_container("ba");
Packit a4aae4
        cont_ba->append_attr("name", "String", "fred");
Packit a4aae4
Packit a4aae4
        cont_c = at1->append_container("c");
Packit a4aae4
        cont_ca = cont_c->append_container("ca");
Packit a4aae4
        cont_caa = cont_ca->append_container("caa");
Packit a4aae4
        cont_caa->append_attr("color", "String", "red");
Packit a4aae4
Packit a4aae4
        // This AttrTable looks like:
Packit a4aae4
        //      Attributes {
Packit a4aae4
        //          a {
Packit a4aae4
        //              Int32 size 7;
Packit a4aae4
        //              String type cars;
Packit a4aae4
        //          }
Packit a4aae4
        //          b {
Packit a4aae4
        //              Int32 number 1;
Packit a4aae4
        //              String type houses;
Packit a4aae4
        //              ba {
Packit a4aae4
        //                  String name fred;
Packit a4aae4
        //              }
Packit a4aae4
        //          }
Packit a4aae4
        //          c {
Packit a4aae4
        //              ca {
Packit a4aae4
        //                  caa {
Packit a4aae4
        //                      String color red;
Packit a4aae4
        //                  }
Packit a4aae4
        //              }
Packit a4aae4
        //          }
Packit a4aae4
        //      }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void tearDown()
Packit a4aae4
    {
Packit a4aae4
        delete at1;
Packit a4aae4
        at1 = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    bool re_match(Regex &r, const char *s)
Packit a4aae4
    {
Packit a4aae4
        return r.match(s, strlen(s)) == (int) strlen(s);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE (AttrTableTest);
Packit a4aae4
#if 1
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST (clone_test);
Packit a4aae4
    CPPUNIT_TEST (find_container_test);
Packit a4aae4
    CPPUNIT_TEST (get_parent_test);
Packit a4aae4
    CPPUNIT_TEST (recurrsive_find_test);
Packit a4aae4
    CPPUNIT_TEST (find_test);
Packit a4aae4
    CPPUNIT_TEST (copy_ctor);
Packit a4aae4
    CPPUNIT_TEST (assignment);
Packit a4aae4
    CPPUNIT_TEST (erase_test);
Packit a4aae4
    CPPUNIT_TEST (names_with_spaces_test);
Packit a4aae4
#endif
Packit a4aae4
    CPPUNIT_TEST (containers_with_spaces_test);
Packit a4aae4
#if 1
Packit a4aae4
    CPPUNIT_TEST (get_attr_iter_test);
Packit a4aae4
    CPPUNIT_TEST (del_attr_table_test);
Packit a4aae4
    CPPUNIT_TEST (append_attr_vector_test);
Packit a4aae4
#endif
Packit a4aae4
#if 0
Packit a4aae4
    CPPUNIT_TEST(print_xml_test);
Packit a4aae4
#endif
Packit a4aae4
Packit a4aae4
    CPPUNIT_TEST_SUITE_END();
Packit a4aae4
Packit a4aae4
    // Tests for methods
Packit a4aae4
Packit a4aae4
    // This is to test for leaks in the clone() method.
Packit a4aae4
    void clone_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable *att = new AttrTable;
Packit a4aae4
        att->append_container(new AttrTable(*cont_a), "copy_of_a");
Packit a4aae4
        delete att;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void recurrsive_find_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable::Attr_iter location;
Packit a4aae4
        AttrTable *a = at1->recurrsive_find("color", &location);
Packit a4aae4
        CPPUNIT_ASSERT(a && a == cont_caa && a->get_name(location) == "color");
Packit a4aae4
Packit a4aae4
        a = cont_caa->recurrsive_find("color", &location);
Packit a4aae4
        CPPUNIT_ASSERT(a && a == cont_caa && a->get_name(location) == "color");
Packit a4aae4
Packit a4aae4
        a = at1->recurrsive_find("ba", &location);
Packit a4aae4
        CPPUNIT_ASSERT(a && a == cont_b && a->get_name(location) == "ba");
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void get_parent_test()
Packit a4aae4
    {
Packit a4aae4
        CPPUNIT_ASSERT(cont_caa->get_parent() == cont_ca);
Packit a4aae4
        CPPUNIT_ASSERT(cont_ca->get_parent() == cont_c);
Packit a4aae4
        CPPUNIT_ASSERT(cont_c->get_parent() == at1);
Packit a4aae4
        CPPUNIT_ASSERT(at1->get_parent() == 0);
Packit a4aae4
        CPPUNIT_ASSERT(build_fqn(cont_caa, "color") == "c.ca.caa.color");
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void find_container_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable *tmp = at1->find_container("a");
Packit a4aae4
        CPPUNIT_ASSERT(tmp != 0);
Packit a4aae4
        CPPUNIT_ASSERT(tmp == cont_a);
Packit a4aae4
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("b.ba") == cont_ba);
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("a.b") == 0);
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("c.ca.caa") == cont_caa);
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("caa") == 0);
Packit a4aae4
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("a.size") == 0);
Packit a4aae4
        CPPUNIT_ASSERT(at1->find_container("b.ba.name") == 0);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void find_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable *tmp;
Packit a4aae4
        AttrTable::Attr_iter iter;
Packit a4aae4
        at1->find("a", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(tmp && iter != tmp->attr_end() && tmp->is_container(iter) && tmp->get_name(iter) == "a");
Packit a4aae4
        at1->find("a.size", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            tmp && iter != tmp->attr_end() && !tmp->is_container(iter) && tmp->get_name(iter) == "size"
Packit a4aae4
                && tmp->get_attr(iter) == "7");
Packit a4aae4
        at1->find("b.type", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            tmp && iter != tmp->attr_end() && !tmp->is_container(iter) && tmp->get_name(iter) == "type"
Packit a4aae4
                && tmp->get_attr(iter) == "houses");
Packit a4aae4
        at1->find("c.ca.caa.color", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(
Packit a4aae4
            tmp && iter != tmp->attr_end() && !tmp->is_container(iter) && tmp->get_name(iter) == "color"
Packit a4aae4
                && tmp->get_attr(iter) == "red");
Packit a4aae4
        at1->find("d.size", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(!tmp);
Packit a4aae4
        at1->find("c.size", &tmp, &iter);
Packit a4aae4
        CPPUNIT_ASSERT(tmp == cont_c && iter == tmp->attr_end());
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void copy_ctor()
Packit a4aae4
    {
Packit a4aae4
        AttrTable at2 = *at1;
Packit a4aae4
        AttrTable::Attr_iter piter = at2.attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "a");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        AttrTable *tmp = at2.get_attr_table(piter);
Packit a4aae4
        AttrTable::Attr_iter qiter = tmp->attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "b");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "c");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void assignment()
Packit a4aae4
    {
Packit a4aae4
        AttrTable at2;
Packit a4aae4
        at2 = *at1;
Packit a4aae4
Packit a4aae4
        AttrTable::Attr_iter piter = at2.attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "a");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        AttrTable *tmp = at2.get_attr_table(piter);
Packit a4aae4
        AttrTable::Attr_iter qiter = tmp->attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "b");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "c");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void erase_test()
Packit a4aae4
    {
Packit a4aae4
        // Copy at1 to at2 and verify that at2 is full of stuff...
Packit a4aae4
        AttrTable at2 = *at1;
Packit a4aae4
        AttrTable::Attr_iter piter = at2.attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "a");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        AttrTable *tmp = at2.get_attr_table(piter);
Packit a4aae4
        AttrTable::Attr_iter qiter = tmp->attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "b");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
        piter++;
Packit a4aae4
        CPPUNIT_ASSERT(at2.get_name(piter) == "c");
Packit a4aae4
        CPPUNIT_ASSERT(at2.is_container(piter));
Packit a4aae4
Packit a4aae4
        at2.erase();
Packit a4aae4
        CPPUNIT_ASSERT(at2.attr_map.size() == 0);
Packit a4aae4
        CPPUNIT_ASSERT(at2.d_name == "");
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void names_with_spaces_test()
Packit a4aae4
    {
Packit a4aae4
        // Create an AttrTable where some names have spaces. The spaces
Packit a4aae4
        // should be replaced by %20 escapes.
Packit a4aae4
        // Replacing the spaces with %20 was the bad, old, behavior. Now
Packit a4aae4
        // the spaces can stay. If someone is writing a DAS using the {}
Packit a4aae4
        // notation, they can use '%20' for the spaces. In the printed
Packit a4aae4
        // DAS using the {} notation, spaces will be represented by %20.
Packit a4aae4
        AttrTable *t = new AttrTable;
Packit a4aae4
        t->append_attr("long name", "String", "first");
Packit a4aae4
        t->append_attr("longer name", "String", "\"second test\"");
Packit a4aae4
        //string sof;
Packit a4aae4
        ostringstream oss;
Packit a4aae4
        t->print(oss, "");
Packit a4aae4
        //FILE2string(sof, of, t->print(of, ""));
Packit a4aae4
        string attrs = "String long%20name \"first\";\n\
Packit a4aae4
String longer%20name \"second test\";";
Packit a4aae4
        //CPPUNIT_ASSERT(sof.find(attrs) != string::npos);
Packit a4aae4
        CPPUNIT_ASSERT(oss.str().find(attrs) != string::npos);
Packit a4aae4
        delete t;
Packit a4aae4
        t = 0;
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void containers_with_spaces_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable *top = new AttrTable;
Packit a4aae4
        try {
Packit a4aae4
            AttrTable *cont = top->append_container("Data Field");
Packit a4aae4
            cont->append_attr("long name", "String", "first");
Packit a4aae4
            cont->add_value_alias(top, "an alias", "long name");
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            cerr << e.get_error_message() << endl;
Packit a4aae4
            CPPUNIT_ASSERT("Caught Error exception!" && false);
Packit a4aae4
        }
Packit a4aae4
        try {
Packit a4aae4
            ostringstream oss;
Packit a4aae4
            top->print(oss);
Packit a4aae4
            Regex r(
Packit a4aae4
                ".*Data%20Field \\{\n\
Packit a4aae4
.*String long%20name \"first\";\n\
Packit a4aae4
.*Alias an%20alias long%20name;\n\
Packit a4aae4
.*\\}\n");
Packit a4aae4
            DBG(cout << ">" << oss.str() << "<" << endl);
Packit a4aae4
            CPPUNIT_ASSERT(re_match(r, oss.str().c_str()));
Packit a4aae4
            delete top;
Packit a4aae4
            top = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            cerr << e.get_error_message() << endl;
Packit a4aae4
            CPPUNIT_ASSERT("Caught Error exception!" && false);
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void get_attr_iter_test()
Packit a4aae4
    {
Packit a4aae4
        int n = at1->get_size();
Packit a4aae4
        CPPUNIT_ASSERT(n == 3);
Packit a4aae4
Packit a4aae4
        AttrTable::Attr_iter i = at1->get_attr_iter(0);
Packit a4aae4
        CPPUNIT_ASSERT(at1->get_name(i) == "a");
Packit a4aae4
        i = at1->get_attr_iter(2);
Packit a4aae4
        CPPUNIT_ASSERT(at1->get_name(i) == "c");
Packit a4aae4
Packit a4aae4
        i = at1->get_attr_iter(1);
Packit a4aae4
        CPPUNIT_ASSERT(at1->is_container(i));
Packit a4aae4
        AttrTable *t1 = at1->get_attr_table(i);
Packit a4aae4
        AttrTable::Attr_iter k = t1->get_attr_iter(1);
Packit a4aae4
        CPPUNIT_ASSERT(t1->get_name(k) == "type");
Packit a4aae4
        CPPUNIT_ASSERT(t1->get_attr(k, 0) == "houses");
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void del_attr_table_test()
Packit a4aae4
    {
Packit a4aae4
        AttrTable *b = at1->find_container("b");
Packit a4aae4
        AttrTable::Attr_iter i = b->attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(b->get_name(i) == "number");
Packit a4aae4
        i += 2;
Packit a4aae4
        CPPUNIT_ASSERT(b->get_name(i) == "ba");
Packit a4aae4
Packit a4aae4
        b->del_attr_table(i);
Packit a4aae4
Packit a4aae4
        i = b->attr_begin();
Packit a4aae4
        CPPUNIT_ASSERT(b->get_name(i) == "number");
Packit a4aae4
        i += 2;
Packit a4aae4
        CPPUNIT_ASSERT(i == b->attr_end());
Packit a4aae4
Packit a4aae4
        // try a second table. at2 contains a scalar attribute followed by a
Packit a4aae4
        // container named 'a'.
Packit a4aae4
        AttrTable *at2;
Packit a4aae4
        try {
Packit a4aae4
            at2 = new AttrTable;
Packit a4aae4
            at2->set_name("at2");
Packit a4aae4
            at2->append_attr("color", "String", "red");
Packit a4aae4
            AttrTable *cont_at2 = at2->append_container("cont_at2");
Packit a4aae4
            cont_at2->append_attr("size", "Int32", "7");
Packit a4aae4
            cont_at2->append_attr("type", "String", "cars");
Packit a4aae4
            i = at2->attr_begin();
Packit a4aae4
            CPPUNIT_ASSERT(at2->get_name(i) == "color");
Packit a4aae4
            i++;
Packit a4aae4
            CPPUNIT_ASSERT(at2->get_name(i) == "cont_at2");
Packit a4aae4
Packit a4aae4
            at2->del_attr_table(i);
Packit a4aae4
Packit a4aae4
            i = at2->attr_begin();
Packit a4aae4
            CPPUNIT_ASSERT(at2->get_name(i) == "color");
Packit a4aae4
            i++;
Packit a4aae4
            CPPUNIT_ASSERT(i == at2->attr_end());
Packit a4aae4
Packit a4aae4
            delete at2;
Packit a4aae4
            at2 = 0;
Packit a4aae4
        }
Packit a4aae4
        catch (Error &e) {
Packit a4aae4
            cerr << "Error: " << e.get_error_message() << endl;
Packit a4aae4
            delete at2;
Packit a4aae4
            at2 = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
        catch (...) {
Packit a4aae4
            cerr << "caught an exception!" << endl;
Packit a4aae4
            delete at2;
Packit a4aae4
            at2 = 0;
Packit a4aae4
            throw;
Packit a4aae4
        }
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void append_attr_vector_test()
Packit a4aae4
    {
Packit a4aae4
        // ("size", "Int32", "7")
Packit a4aae4
        vector<string> vs;
Packit a4aae4
        vs.push_back("8");
Packit a4aae4
        vs.push_back("9");
Packit a4aae4
        cont_a->append_attr("size", "Int32", &vs);
Packit a4aae4
Packit a4aae4
        CPPUNIT_ASSERT(cont_a->get_attr("size", 0) == "7");
Packit a4aae4
        CPPUNIT_ASSERT(cont_a->get_attr("size", 1) == "8");
Packit a4aae4
        CPPUNIT_ASSERT(cont_a->get_attr("size", 2) == "9");
Packit a4aae4
        CPPUNIT_ASSERT(cont_a->get_attr_num("size") == 3);
Packit a4aae4
    }
Packit a4aae4
Packit a4aae4
    void print_xml_test()
Packit a4aae4
    {
Packit a4aae4
        at1->print_xml(stdout);
Packit a4aae4
    }
Packit a4aae4
};
Packit a4aae4
Packit a4aae4
CPPUNIT_TEST_SUITE_REGISTRATION (AttrTableTest);
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: AttrTableTest has the following tests:" << endl;
Packit a4aae4
            const std::vector<Test*> &tests = libdap::AttrTableTest::suite()->getTests();
Packit a4aae4
            unsigned int prefix_len = libdap::AttrTableTest::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::AttrTableTest::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
}