Logo Search packages:      
Sourcecode: tagcoll version File versions  Download package

test-textformat.cc

/*
 * Test TDBDiskIndex
 *
 * Copyright (C) 2005  Enrico Zini <enrico@debian.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <test-utils.h>
#include <tagcoll/TextFormat.h>
#include <tagcoll/StringParserInput.h>
#include <tagcoll/TDBIndexer.h>
#include <tagcoll/Exception.h>
#include <unistd.h>
#include <string.h>

#include <tagcoll/TextFormat.cc>
#include <tagcoll/TDBIndexer.cc>

using namespace std;
using namespace Tagcoll;
using namespace tut_tagcoll;

// Item to use for testing (can have a NULL value, and leaks memory for simplicity)
class Item
{
protected:
      const char* data;
public:
      Item(const char* data = 0) {
            if (data)
                  this->data = strdup(data);
            else
                  this->data = 0;
      }
      Item(const std::string& data) {
            if (data.empty())
                  this->data = 0;
            else
                  this->data = strdup(data.c_str());
      }
      Item(const Item& i) : data(i.data) {}
      Item& operator=(const Item& i) { data = i.data; return *this; }
      bool operator==(const Item& ns) const throw ()
      {
            if (data == 0 && ns.data == 0)
                  return true;
            if (! (data && ns.data))
                  return false;
            return strcmp(data, ns.data) == 0;
      }
      bool operator<(const Item& ns) const throw () 
      {
            if (data == 0 && ns.data == 0)
                  return false;
            if (data == 0 && ns.data != 0)
                  return true;
            if (data != 0 && ns.data == 0)
                  return false;
            return strcmp(data, ns.data) < 0;
      }
      operator bool() const throw () { return data != 0; }
      operator std::string() const throw () { return data == 0 ? string() : string(data); }
      string getData() const throw () { return string(data); }
};

// Serializer to use for testing (can return NULL values)
namespace Tagcoll {

template<>
class Converter<Item, string>
{
public:
      string operator()(const Item& item) { return item.getData(); }
      OpSet<string> operator()(const OpSet<Item>& items)
      {
            OpSet<string> res;
            for (OpSet<Item>::const_iterator i = items.begin();
                        i != items.end(); i++)
            {
                  string t = (*this)(*i);
                  if (!t.empty())
                        res += t;
            }
            return res;
      }
};

template<>
class Converter<string, Item>
{
public:
      Item operator()(const string& item)
      {
            if (item == "null")
                  return Item(0);
            return Item(item.c_str());
      }
      OpSet<Item> operator()(const OpSet<string>& items)
      {
            OpSet<Item> res;
            for (OpSet<string>::const_iterator i = items.begin();
                        i != items.end(); i++)
            {
                  Item t = (*this)(*i);
                  if (t)
                        res += t;
            }
            return res;
      }
};

}

#define INSTANTIATING_TEMPLATES
#undef COMPILE_TESTSUITE
#include <tagcoll/OpSet.cc>
#include <tagcoll/Patches.cc>
template class OpSet<Item>;
template class Consumer<Item, Item>;
template class Patch<Item, Item>;
template class PatchList<Item, Item>;
template class TDBIndexer<Item, Item>;
#undef INSTANTIATING_TEMPLATES

class ItemChecker : public Consumer<Item, Item>
{
protected:
      int nullitems;
      int nulltags;

      void consumeItemUntagged(const Item& item)
      {
            if (!item) nullitems++;
      }
      void consumeItem(const Item& item, const OpSet<Item>& tags)
      {
            if (!item)
                  nullitems++;
            for (OpSet<Item>::const_iterator i = tags.begin();
                        i != tags.end(); i++)
                  if (!*i)
                        nulltags++;
      }
public:
      ItemChecker() : nullitems(0), nulltags(0) {}

      int nullItems() const throw () { return nullitems; }
      int nullTags() const throw () { return nulltags; }
};

static const char* testCollection =
      "1: b, c, d\n"
      "2: a, b, c\n"
      "3: a, d, c, null\n"
      "4: d, c, a\n"
      "null: d, c, a\n"
      "null: d, null\n";

static const char* testPatch =
      "1: +a\n"
      "2: +a, -b, +null\n"
      "3: +d, -c, -a\n"
      "null: +a, -d, -c\n"
      "null: +a, -null, -c\n";
      

namespace tut {

struct tagcoll_tests_textformat_shar {
};
TESTGRP(tagcoll_tests_textformat);

template<> template<>
void to::test<1> ()
{
      Converter<string, Item> toitem;
      try {
            // Parse the sample collection
            StringParserInput in0(testCollection);
            TDBIndexer<Item, Item> coll;
            ItemChecker checker;
            TextFormat<Item, Item>::parse(toitem, toitem, in0, checker);
            ensure_equals(checker.nullItems(), 2);
            ensure_equals(checker.nullTags(), 2);
            
            StringParserInput in1(testCollection);
            TextFormat<Item, Item>::parse(toitem, toitem, in1, coll);

            gen_ensure(coll.hasItem("1"));
            gen_ensure(coll.hasItem("2"));
            gen_ensure(coll.hasItem("3"));
            gen_ensure(coll.hasItem("4"));
            gen_ensure(!coll.hasItem(Item()));

            gen_ensure(coll.hasTag("a"));
            gen_ensure(coll.hasTag("b"));
            gen_ensure(coll.hasTag("c"));
            gen_ensure(coll.hasTag("d"));
            gen_ensure(!coll.hasTag(Item()));
      } catch (Exception& e) {
            fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
            throw;
      }
}

template<> template<>
void to::test<2> ()
{
      Converter<string, Item> toitem;
      try {
            // Parse the sample patch
            StringParserInput in0(testPatch);
            PatchList<Item, Item> patch = TextFormat<Item, Item>::parsePatch(toitem, toitem, in0);

            gen_ensure(patch.find("1") != patch.end());
            gen_ensure(patch.find("2") != patch.end());
            gen_ensure(patch.find("3") != patch.end());
            gen_ensure(patch.find("4") == patch.end());
            gen_ensure(patch.find(Item()) == patch.end());

            gen_ensure(patch.find("1")->second.getAdded().size() == 1);
            gen_ensure(patch.find("1")->second.getRemoved().size() == 0);
            gen_ensure(patch.find("1")->second.getAdded().contains("a"));
            gen_ensure(!patch.find("1")->second.getAdded().contains(Item()));
            gen_ensure(!patch.find("1")->second.getRemoved().contains(Item()));

            gen_ensure(patch.find("2")->second.getAdded().size() == 1);
            gen_ensure(patch.find("2")->second.getRemoved().size() == 1);
            gen_ensure(patch.find("2")->second.getAdded().contains("a"));
            gen_ensure(patch.find("2")->second.getRemoved().contains("b"));
            gen_ensure(!patch.find("2")->second.getAdded().contains(Item()));
            gen_ensure(!patch.find("2")->second.getRemoved().contains(Item()));

            gen_ensure(patch.find("3")->second.getAdded().size() == 1);
            gen_ensure(patch.find("3")->second.getRemoved().size() == 2);
            gen_ensure(patch.find("3")->second.getAdded().contains("d"));
            gen_ensure(patch.find("3")->second.getRemoved().contains("c"));
            gen_ensure(patch.find("3")->second.getRemoved().contains("a"));
            gen_ensure(!patch.find("3")->second.getAdded().contains(Item()));
            gen_ensure(!patch.find("3")->second.getRemoved().contains(Item()));
      } catch (Exception& e) {
            fprintf(stderr, "%s: %.*s\n", e.type(), PFSTR(e.desc()));
            throw;
      }
}

}

// vim:set ts=4 sw=4:

Generated by  Doxygen 1.6.0   Back to index