/*
 * Project: MoleCuilder
 * Description: creates and alters molecular systems
 * Copyright (C)  2012 University of Bonn. All rights reserved.
 * 
 *
 *   This file is part of MoleCuilder.
 *
 *    MoleCuilder 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.
 *
 *    MoleCuilder 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 MoleCuilder.  If not, see .
 */
/*
 * IndexedVectorsUnitTest.cpp
 *
 *  Created on: Jul 29, 2012
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
using namespace std;
#include 
#include 
#include 
#include "IndexedVectorsUnitTest.hpp"
#include 
#include 
#include 
#include "CodePatterns/Assert.hpp"
#ifdef HAVE_TESTRUNNER
#include "UnitTestMain.hpp"
#endif /*HAVE_TESTRUNNER*/
using namespace boost::assign;
/********************************************** Test classes **************************************/
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( IndexedVectorsTest );
void IndexedVectorsTest::setUp()
{
  // failing asserts should be thrown
  ASSERT_DO(Assert::Throw);
  // create two vector_t
  ones += 1.,1.,1.;
  twos += 2.,2.,2.;
  threes += 3.,3.,3.;
  CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, ones.size() );
  CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, twos.size() );
  CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, threes.size() );
  // create vectors
  IndexedVectors::vectors_t vectors;
  vectors.push_back(ones);
  vectors.push_back(twos);
  IndexedVectors::vectors_t othervectors;
  othervectors.push_back(threes);
  othervectors.push_back(threes);
  // create two indices
  IndexedVectors::indices_t indices;
  indices += 1,2;
  IndexedVectors::indices_t otherindices;
  otherindices += 1,3;
  // create indexed vectors
  ivectors = new IndexedVectors(indices, vectors);
  otherivectors = new IndexedVectors(otherindices, othervectors);
}
void IndexedVectorsTest::tearDown()
{
  delete ivectors;
  delete otherivectors;
}
/** UnitTest for cstor's
 */
void IndexedVectorsTest::Constructor_Test()
{
  // check whether -1 is dropped
  IndexedVectors::indices_t indices;
  indices += 1,-1,3;
  IndexedVectors::vectors_t vectors;
  vectors.push_back(ones);
  vectors.push_back(twos);
  vectors.push_back(threes);
  IndexedVectors testivectors(indices, vectors);
  CPPUNIT_ASSERT_EQUAL( (size_t)2, testivectors.vectors.size() );
  CPPUNIT_ASSERT_EQUAL( ones, testivectors.vectors[1] );
  CPPUNIT_ASSERT_EQUAL( threes, testivectors.vectors[3] );
  CPPUNIT_ASSERT( testivectors.vectors.find(-1) == testivectors.vectors.end() );
}
/** UnitTest for operator+=()
 */
void IndexedVectorsTest::operatorPlusEqual_Test()
{
  // safeguard initial sizes
  CPPUNIT_ASSERT_EQUAL( (size_t)2, ivectors->vectors.size() );
  CPPUNIT_ASSERT_EQUAL( (size_t)2, otherivectors->vectors.size() );
  // perform operation
  *ivectors += *otherivectors;
  // check new and ole sizes
  CPPUNIT_ASSERT_EQUAL( (size_t)3, ivectors->vectors.size() );
  CPPUNIT_ASSERT_EQUAL( (size_t)2, otherivectors->vectors.size() );
  // then check result
  IndexedVectors::vector_t result( IndexedVectors::nullvector );
  CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, result.size() );
  for (size_t i=0; ivectors.begin();
      iter != ivectors->vectors.end(); ++iter) {
    CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, iter->second.size() );
  }
  CPPUNIT_ASSERT_EQUAL( result, ivectors->vectors[1] );
  CPPUNIT_ASSERT_EQUAL( twos, ivectors->vectors[2] );
  CPPUNIT_ASSERT_EQUAL( threes, ivectors->vectors[3] );
}
/** UnitTest for operator-=()
 */
void IndexedVectorsTest::operatorMinusEqual_Test()
{
  // safeguard initial sizes
  CPPUNIT_ASSERT_EQUAL( (size_t)2, ivectors->vectors.size() );
  CPPUNIT_ASSERT_EQUAL( (size_t)2, otherivectors->vectors.size() );
  // perform operation
  *ivectors -= *otherivectors;
  // check new and ole sizes
  CPPUNIT_ASSERT_EQUAL( (size_t)3, ivectors->vectors.size() );
  CPPUNIT_ASSERT_EQUAL( (size_t)2, otherivectors->vectors.size() );
  // then check result
  IndexedVectors::vector_t result( IndexedVectors::nullvector );
  IndexedVectors::vector_t thirdresult( IndexedVectors::nullvector );
  CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, result.size() );
  for (size_t i=0; ivectors.begin();
      iter != ivectors->vectors.end(); ++iter) {
    CPPUNIT_ASSERT_EQUAL( IndexedVectors::FixedSize, iter->second.size() );
  }
  CPPUNIT_ASSERT_EQUAL( result, ivectors->vectors[1] );
  CPPUNIT_ASSERT_EQUAL( twos, ivectors->vectors[2] );
  CPPUNIT_ASSERT_EQUAL( thirdresult, ivectors->vectors[3] );
}