/*
 * 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 .
 */
/*
 * MPQCCommandJobUnitTest.cpp
 *
 *  Created on: Feb 08, 2012
 *      Author: heber
 */
// include config.h
#ifdef HAVE_CONFIG_H
#include 
#endif
#include 
#include 
#include 
// include headers that implement a archive in simple text format
#include 
#include 
#include 
#include "MPQCCommandJobUnitTest.hpp"
#include "Jobs/MPQCCommandJob.hpp"
#include "CodePatterns/Assert.hpp"
#include "CodePatterns/Log.hpp"
#ifdef HAVE_TESTRUNNER
#include "UnitTestMain.hpp"
#endif /*HAVE_TESTRUNNER*/
/********************************************** Test classes **************************************/
const std::string resultstring="\
\n\
  HOMO is     5   A =  -0.498625\n\
  LUMO is     6   A =   0.251360\n\
\n\
  total scf energy =  -75.5133625967\n\
\n\
  Memory used for integral intermediates: 56628 Bytes\n\
\n\
    10  -0.02171957  3   A  3   A ->  6   A  6   A (+-+-)\n\
\n\
  RHF energy [au]:                    -75.513362596662\n\
  MP2 correlation energy [au]:         -0.124136686358\n\
  MP2 energy [au]:                    -75.637499283020\n\
\n\
  D1(MP2)                =   0.01063314\n\
\n\
  CPHF: iter =  7 rms(P) = 0.0000000011 eps = 0.0000000100\n\
\n\
  Total MP2 gradient [au]:\n\
       1   O   0.1100072224   0.0000000000  -0.0000000000\n\
       2   H  -0.0550036112  -0.0000000000  -0.1562140155\n\
       3   H  -0.0550036112  -0.0000000000   0.1562140155\n\
\n\
  Value of the MolecularEnergy:  -75.6374992830\n\
\n\
";
// Registers the fixture into the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( MPQCCommandJobTest );
void MPQCCommandJobTest::setUp()
{
  // Throw assertions
  ASSERT_DO(Assert::Throw);
  setVerbosity(4);
  job = new MPQCCommandJob(std::string("empty"), 1);
}
void MPQCCommandJobTest::tearDown()
{
  delete job;
}
/** UnitTest for extractString()
 */
void MPQCCommandJobTest::extractStringTest()
{
  // prepare result container
  MPQCData data;
  data.energy = -75.637499283020;
  std::vector force;
  std::vector< std::vector > forces;
  //  1   O   0.1100072224   0.0000000000  -0.0000000000
  force.push_back(0.1100072224);
  force.push_back(0.0000000000);
  force.push_back(-0.0000000000);
  data.forces.push_back( force );
  //  2   H  -0.0550036112  -0.0000000000  -0.1562140155
  force.clear();
  force.push_back(-0.0550036112);
  force.push_back(-0.0000000000);
  force.push_back(-0.1562140155);
  data.forces.push_back( force );
  //  3   H  -0.0550036112  -0.0000000000   0.1562140155
  force.clear();
  force.push_back(-0.0550036112);
  force.push_back(-0.0000000000);
  force.push_back(0.1562140155);
  data.forces.push_back( force );
  // extract and check
  FragmentResult::ptr result = job->extractResult(resultstring);
  std::stringstream returnstream(result->result);
  // deserialize
  MPQCData extractedData;
  boost::archive::text_iarchive ia(returnstream);
  ia >> extractedData;
  CPPUNIT_ASSERT( data == extractedData );
}
/** UnitTest for operator==()
 */
void MPQCCommandJobTest::operatorTest()
{
  MPQCCommandJob otherJob(std::string("empty"), 1);
  // ascertain equality
  CPPUNIT_ASSERT( *job == otherJob );
  // parse results
  FragmentResult::ptr result = job->extractResult(resultstring);
  // ascertain unequality as now data should differ
  CPPUNIT_ASSERT( *job != otherJob );
}
/** UnitTest for serialization
 */
void MPQCCommandJobTest::serializationTest()
{
  // parse results
  FragmentResult::ptr result = job->extractResult(resultstring);
  // serialize
  std::stringstream outputstream;
  boost::archive::text_oarchive oa(outputstream);
  oa << job;
  // deserialize
  MPQCCommandJob *extractedJob;
  std::stringstream returnstream(outputstream.str());
  boost::archive::text_iarchive ia(returnstream);
  ia >> extractedJob;
  CPPUNIT_ASSERT( *job == *extractedJob );
  delete extractedJob;
}