mirror of https://github.com/vitalif/grive2
load and save from .grive_state and build the resource tree
parent
3dd3f544fb
commit
dfbe859531
|
@ -117,6 +117,7 @@ int main( int argc, char **argv )
|
|||
Drive drive( token ) ;
|
||||
|
||||
drive.Update() ;
|
||||
// drive.SaveState() ;
|
||||
|
||||
config.Save() ;
|
||||
}
|
||||
|
|
|
@ -97,6 +97,7 @@ Drive::Drive( OAuth2& auth ) :
|
|||
if ( file.Kind() != "folder" )
|
||||
{
|
||||
Resource *p = m_state.FindFolderByHref( file.ParentHref() ) ;
|
||||
Trace( "finding parent of %1%: %2%", file.Title(), (void*)p ) ;
|
||||
if ( file.Filename().empty() )
|
||||
Log( "file \"%1%\" is a google document, ignored", file.Title() ) ;
|
||||
|
||||
|
@ -122,7 +123,10 @@ Drive::Drive( OAuth2& auth ) :
|
|||
resp = xrsp.Response() ;
|
||||
}
|
||||
} while ( has_next ) ;
|
||||
|
||||
}
|
||||
|
||||
void Drive::SaveState()
|
||||
{
|
||||
m_state.Write( state_file ) ;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public :
|
|||
|
||||
void Update() ;
|
||||
void Sync() ;
|
||||
void SaveState() ;
|
||||
|
||||
struct Error : virtual Exception {} ;
|
||||
|
||||
|
|
|
@ -56,6 +56,25 @@ Entry::Entry( const fs::path& path ) :
|
|||
{
|
||||
}
|
||||
|
||||
Entry::Entry(
|
||||
const std::string& name,
|
||||
const std::string& resource_id,
|
||||
const std::string& href,
|
||||
const std::string& md5,
|
||||
const std::string& kind,
|
||||
const DateTime& mtime,
|
||||
const std::string& parent_href ) :
|
||||
m_title ( name ),
|
||||
m_filename ( name ),
|
||||
m_kind ( kind ),
|
||||
m_md5 ( md5 ),
|
||||
m_resource_id ( resource_id ),
|
||||
m_parent_hrefs ( 1, parent_href ),
|
||||
m_self_href ( href ),
|
||||
m_mtime ( mtime )
|
||||
{
|
||||
}
|
||||
|
||||
void Entry::Update( const xml::Node& n )
|
||||
{
|
||||
m_title = n["title"] ;
|
||||
|
|
|
@ -45,6 +45,14 @@ public :
|
|||
Entry( ) ;
|
||||
explicit Entry( const fs::path& path ) ;
|
||||
explicit Entry( const xml::Node& n ) ;
|
||||
explicit Entry(
|
||||
const std::string& name,
|
||||
const std::string& resource_id,
|
||||
const std::string& href,
|
||||
const std::string& md5,
|
||||
const std::string& kind,
|
||||
const DateTime& mtime,
|
||||
const std::string& parent_href ) ;
|
||||
|
||||
std::string Title() const ;
|
||||
std::string Filename() const ;
|
||||
|
@ -78,7 +86,6 @@ private :
|
|||
|
||||
std::string m_self_href ;
|
||||
std::string m_content_src ;
|
||||
std::string m_parent_href ;
|
||||
std::string m_upload_link ;
|
||||
|
||||
DateTime m_mtime ;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "http/Download.hh"
|
||||
#include "http/StringResponse.hh"
|
||||
#include "http/XmlResponse.hh"
|
||||
#include "protocol/Json.hh"
|
||||
#include "util/Crypt.hh"
|
||||
#include "util/Log.hh"
|
||||
#include "util/OS.hh"
|
||||
|
@ -44,6 +45,21 @@ Resource::Resource() :
|
|||
{
|
||||
}
|
||||
|
||||
/// construct from previously serialized JSON object
|
||||
Resource::Resource( const Json& json, Resource *parent ) :
|
||||
m_entry (
|
||||
json["name"].Str(),
|
||||
json["id"].Str(),
|
||||
json["href"].Str(),
|
||||
json["md5"].Str(),
|
||||
json["kind"].Str(),
|
||||
DateTime( json["mtime"]["sec"].Int(), json["mtime"]["nsec"].Int() ),
|
||||
parent != 0 ? parent->SelfHref() : "" ),
|
||||
m_parent( parent ),
|
||||
m_state( local_new )
|
||||
{
|
||||
}
|
||||
|
||||
Resource::Resource( const xml::Node& entry ) :
|
||||
m_entry ( entry ),
|
||||
m_parent( 0 ),
|
||||
|
@ -58,16 +74,6 @@ Resource::Resource( const Entry& entry, Resource *parent ) :
|
|||
{
|
||||
}
|
||||
|
||||
// Resource::Resource(
|
||||
// const std::string& name,
|
||||
// const std::string& kind,
|
||||
// const std::string& href ) :
|
||||
// m_entry ( name, kind, href ),
|
||||
// m_parent( 0 ),
|
||||
// m_state ( local_new )
|
||||
// {
|
||||
// }
|
||||
|
||||
Resource::Resource( const fs::path& path ) :
|
||||
m_entry ( path ),
|
||||
m_parent( 0 ),
|
||||
|
@ -127,7 +133,7 @@ std::string Resource::ParentHref() const
|
|||
void Resource::AddChild( Resource *child )
|
||||
{
|
||||
assert( child != 0 ) ;
|
||||
assert( child->m_parent == 0 ) ;
|
||||
assert( child->m_parent == 0 || child->m_parent == this ) ;
|
||||
assert( child != this ) ;
|
||||
|
||||
child->m_parent = this ;
|
||||
|
@ -285,6 +291,46 @@ bool Resource::Upload( http::Agent* http, std::streambuf *file, const http::Head
|
|||
return true ;
|
||||
}
|
||||
|
||||
Json Resource::Serialize() const
|
||||
{
|
||||
Json result ;
|
||||
result.Add( "name", Json(Name()) ) ;
|
||||
result.Add( "id", Json(ResourceID()) ) ;
|
||||
result.Add( "href", Json(SelfHref()) ) ;
|
||||
result.Add( "md5", Json(m_entry.MD5()) ) ;
|
||||
result.Add( "kind", Json(m_entry.Kind()) ) ;
|
||||
|
||||
Json mtime ;
|
||||
mtime.Add( "sec", Json(m_entry.MTime().Sec() ) );
|
||||
mtime.Add( "nsec", Json(m_entry.MTime().NanoSec() ) );
|
||||
|
||||
result.Add( "mtime",mtime ) ;
|
||||
|
||||
std::vector<Json> array ;
|
||||
for ( std::vector<Resource*>::const_iterator i = m_child.begin() ; i != m_child.end() ; ++i )
|
||||
array.push_back( (*i)->Serialize() ) ;
|
||||
|
||||
result.Add( "child", Json(array) ) ;
|
||||
|
||||
return result ;
|
||||
|
||||
}
|
||||
|
||||
Resource::iterator Resource::begin() const
|
||||
{
|
||||
return m_child.begin() ;
|
||||
}
|
||||
|
||||
Resource::iterator Resource::end() const
|
||||
{
|
||||
return m_child.end() ;
|
||||
}
|
||||
|
||||
std::size_t Resource::size() const
|
||||
{
|
||||
return m_child.size() ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
||||
namespace std
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
namespace gr {
|
||||
|
||||
class Json ;
|
||||
|
||||
/*! \brief A resource can be a file or a folder in the google drive
|
||||
|
||||
The google drive contains a number of resources, which is represented by this class.
|
||||
|
@ -40,15 +42,15 @@ class Resource
|
|||
public :
|
||||
struct Error : virtual Exception {} ;
|
||||
|
||||
typedef std::vector<Resource*> Children ;
|
||||
typedef Children::const_iterator iterator ;
|
||||
|
||||
public :
|
||||
Resource() ;
|
||||
explicit Resource( const xml::Node& entry ) ;
|
||||
explicit Resource( const Entry& entry, Resource *parent = 0 ) ;
|
||||
explicit Resource( const fs::path& path ) ;
|
||||
// Resource(
|
||||
// const std::string& name,
|
||||
// const std::string& kind,
|
||||
// const std::string& href ) ;
|
||||
explicit Resource( const Json& json, Resource *parent = 0 ) ;
|
||||
void Swap( Resource& coll ) ;
|
||||
|
||||
// default copy ctor & op= are fine
|
||||
|
@ -72,6 +74,13 @@ public :
|
|||
void Sync( http::Agent *http, const http::Headers& auth ) ;
|
||||
void Delete( http::Agent* http, const http::Headers& auth ) ;
|
||||
|
||||
Json Serialize() const ;
|
||||
|
||||
// children access
|
||||
iterator begin() const ;
|
||||
iterator end() const ;
|
||||
std::size_t size() const ;
|
||||
|
||||
private :
|
||||
/// State of the resource. indicating what to do with the resource
|
||||
enum State
|
||||
|
|
|
@ -20,7 +20,9 @@
|
|||
#include "ResourceTree.hh"
|
||||
#include "CommonUri.hh"
|
||||
|
||||
#include "protocol/Json.hh"
|
||||
#include "util/Destroy.hh"
|
||||
#include "util/Log.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
@ -52,10 +54,18 @@ ResourceTree::ResourceTree( const ResourceTree& fs ) :
|
|||
}
|
||||
|
||||
ResourceTree::~ResourceTree( )
|
||||
{
|
||||
Clear() ;
|
||||
}
|
||||
|
||||
void ResourceTree::Clear()
|
||||
{
|
||||
// delete all pointers
|
||||
const Set& s = m_set.get<ByIdentity>() ;
|
||||
std::for_each( s.begin(), s.end(), Destroy() ) ;
|
||||
|
||||
m_set.clear() ;
|
||||
m_root = 0 ;
|
||||
}
|
||||
|
||||
Resource* ResourceTree::Root()
|
||||
|
@ -152,4 +162,30 @@ ResourceTree::iterator ResourceTree::end()
|
|||
return m_set.get<ByIdentity>().end() ;
|
||||
}
|
||||
|
||||
void ResourceTree::Read( const Json& json )
|
||||
{
|
||||
Clear() ;
|
||||
m_root = new Resource( json ) ;
|
||||
AddTree( m_root, json ) ;
|
||||
}
|
||||
|
||||
void ResourceTree::AddTree( Resource *node, const Json& json )
|
||||
{
|
||||
assert( node != 0 ) ;
|
||||
m_set.insert( node ) ;
|
||||
|
||||
std::vector<Json> array = json["child"].AsArray() ;
|
||||
for ( std::vector<Json>::iterator i = array.begin() ; i != array.end() ; ++i )
|
||||
{
|
||||
Resource *c = new Resource( *i, node ) ;
|
||||
node->AddChild( c ) ;
|
||||
AddTree( c, *i ) ;
|
||||
}
|
||||
}
|
||||
|
||||
Json ResourceTree::Serialize() const
|
||||
{
|
||||
return m_root->Serialize() ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
namespace gr {
|
||||
|
||||
class Json ;
|
||||
|
||||
namespace details
|
||||
{
|
||||
using namespace boost::multi_index ;
|
||||
|
@ -73,6 +75,7 @@ public :
|
|||
const Resource* FindByHref( const std::string& href ) const ;
|
||||
|
||||
Resource* FindByPath( const fs::path& path ) ;
|
||||
Resource* FindByID( const std::string& id ) ;
|
||||
|
||||
bool ReInsert( Resource *coll ) ;
|
||||
|
||||
|
@ -85,7 +88,14 @@ public :
|
|||
|
||||
iterator begin() ;
|
||||
iterator end() ;
|
||||
|
||||
|
||||
void Read( const Json& json ) ;
|
||||
Json Serialize() const ;
|
||||
|
||||
private :
|
||||
void Clear() ;
|
||||
void AddTree( Resource *node, const Json& json ) ;
|
||||
|
||||
private :
|
||||
details::Folders m_set ;
|
||||
Resource* m_root ;
|
||||
|
|
|
@ -40,8 +40,7 @@ namespace gr {
|
|||
|
||||
State::State( const fs::path& filename )
|
||||
{
|
||||
if ( fs::exists( filename ) )
|
||||
Read( filename );
|
||||
Read( filename ) ;
|
||||
}
|
||||
|
||||
std::string State::ChangeStamp() const
|
||||
|
@ -68,15 +67,25 @@ void State::FromLocal( const fs::path& p, gr::Resource* folder )
|
|||
|
||||
for ( fs::directory_iterator i( p ) ; i != fs::directory_iterator() ; ++i )
|
||||
{
|
||||
if ( i->path().filename().string()[0] == '.' )
|
||||
Log( "file %1% is ignored by grive", i->path().filename().string(), log::info ) ;
|
||||
std::string fname = i->path().filename().string() ;
|
||||
|
||||
if ( fname[0] == '.' )
|
||||
Log( "file %1% is ignored by grive", fname, log::info ) ;
|
||||
|
||||
else
|
||||
{
|
||||
Resource *c = new Resource( i->path() ) ;
|
||||
folder->AddChild( c ) ;
|
||||
m_res.Insert( c ) ;
|
||||
|
||||
Resource *c = folder->FindChild( fname ) ;
|
||||
if ( c != 0 )
|
||||
{
|
||||
Trace( "wow! file %1% is loaded from previous state", fname ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = new Resource( i->path() ) ;
|
||||
folder->AddChild( c ) ;
|
||||
m_res.Insert( c ) ;
|
||||
}
|
||||
|
||||
if ( fs::is_directory( i->path() ) )
|
||||
FromLocal( *i, c ) ;
|
||||
}
|
||||
|
@ -124,7 +133,11 @@ bool State::Update( const Entry& e )
|
|||
{
|
||||
assert( !e.ParentHref().empty() ) ;
|
||||
|
||||
// Resource *r = m_res.FindByID( e.ResourceID() ) ;
|
||||
Resource *r = m_res.FindByHref( e.SelfHref() ) ;
|
||||
if ( r != 0 )
|
||||
{
|
||||
Trace( "wow! find %1% from state file?", r->Name() ) ;
|
||||
}
|
||||
|
||||
Resource *parent = m_res.FindByHref( e.ParentHref() ) ;
|
||||
if ( parent != 0 )
|
||||
|
@ -183,13 +196,20 @@ State::iterator State::end()
|
|||
|
||||
void State::Read( const fs::path& filename )
|
||||
{
|
||||
Trace( "reading %1%", filename ) ;
|
||||
if ( fs::exists( filename ) )
|
||||
{
|
||||
Json json = Json::ParseFile( filename.string() ) ;
|
||||
|
||||
m_change_stamp = json["change_stamp"].Str() ;
|
||||
m_res.Read( json["rtree"] ) ;
|
||||
}
|
||||
}
|
||||
|
||||
void State::Write( const fs::path& filename ) const
|
||||
{
|
||||
Json result ;
|
||||
result.Add( "change_stamp", Json( m_change_stamp ) ) ;
|
||||
result.Add( "rtree", m_res.Serialize() ) ;
|
||||
|
||||
std::ofstream fs( filename.string().c_str() ) ;
|
||||
fs << result ;
|
||||
|
|
|
@ -34,7 +34,7 @@ Json::Json( ) :
|
|||
m_json( ::json_object_new_object() )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
throw Error() << expt::ErrMsg( "cannot create json object" ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json object" ) ) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -42,7 +42,8 @@ Json::Json( const std::string& str ) :
|
|||
m_json( ::json_object_new_string( str.c_str() ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
throw Error() << expt::ErrMsg( "cannot create json string \"" + str + "\"" ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << expt::ErrMsg( "cannot create json string \"" + str + "\"" ) ) ;
|
||||
|
||||
// paranoid check
|
||||
assert( ::json_object_get_string( m_json ) == str ) ;
|
||||
|
@ -53,7 +54,7 @@ Json::Json( const int& l ) :
|
|||
m_json( ::json_object_new_int( l ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
throw Error() << expt::ErrMsg( "cannot create json int" ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -61,7 +62,15 @@ Json::Json( const long& l ) :
|
|||
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
throw Error() << expt::ErrMsg( "cannot create json int" ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
Json::Json( const unsigned long& l ) :
|
||||
m_json( ::json_object_new_int( static_cast<int>(l) ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
}
|
||||
|
||||
template <>
|
||||
|
@ -69,7 +78,7 @@ Json::Json( const std::vector<Json>& arr ) :
|
|||
m_json( ::json_object_new_array( ) )
|
||||
{
|
||||
if ( m_json == 0 )
|
||||
throw Error() << expt::ErrMsg( "cannot create json int" ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "cannot create json int" ) ) ;
|
||||
|
||||
for ( std::vector<Json>::const_iterator i = arr.begin() ; i != arr.end() ; ++i )
|
||||
Add( *i ) ;
|
||||
|
@ -79,7 +88,7 @@ Json Json::Parse( const std::string& str )
|
|||
{
|
||||
struct json_object *json = ::json_tokener_parse( str.c_str() ) ;
|
||||
if ( json == 0 )
|
||||
throw Error() << expt::ErrMsg( "json parse error" ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "json parse error" ) ) ;
|
||||
|
||||
return Json( json, NotOwned() ) ;
|
||||
}
|
||||
|
@ -98,7 +107,7 @@ Json Json::ParseFile( const std::string& filename )
|
|||
json = ::json_tokener_parse_ex( tok, buf, count ) ;
|
||||
|
||||
if ( json == 0 )
|
||||
throw Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( ::json_tokener_errors[tok->err] ) ) ;
|
||||
|
||||
::json_tokener_free( tok ) ;
|
||||
|
||||
|
@ -152,7 +161,10 @@ Json Json::operator[]( const std::string& key ) const
|
|||
|
||||
struct json_object *j = ::json_object_object_get( m_json, key.c_str() ) ;
|
||||
if ( j == 0 )
|
||||
throw Error() << expt::ErrMsg( "key: " + key + " is not found in object" ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< expt::ErrMsg( "key: " + key + " is not found in object" )
|
||||
<< JsonInfo( *this ) ) ;
|
||||
|
||||
return Json( j ) ;
|
||||
}
|
||||
|
@ -166,7 +178,10 @@ Json Json::operator[]( const std::size_t& idx ) const
|
|||
{
|
||||
std::ostringstream ss ;
|
||||
ss << "index " << idx << " is not found in array" ;
|
||||
throw Error() << expt::ErrMsg( ss.str() ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error()
|
||||
<< expt::ErrMsg( ss.str() )
|
||||
<< JsonInfo( *this ) ) ;
|
||||
}
|
||||
|
||||
return Json( j ) ;
|
||||
|
@ -294,7 +309,8 @@ Json Json::FindInArray( const std::string& key, const std::string& value ) const
|
|||
if ( item.Has(key) && item[key].Str() == value )
|
||||
return item ;
|
||||
}
|
||||
throw Error() << expt::ErrMsg( "cannot find " + key + " = " + value + " in array" ) ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << expt::ErrMsg( "cannot find " + key + " = " + value + " in array" ) ) ;
|
||||
}
|
||||
|
||||
bool Json::FindInArray( const std::string& key, const std::string& value, Json& result ) const
|
||||
|
|
|
@ -36,6 +36,7 @@ public :
|
|||
typedef std::vector<Json> Array ;
|
||||
|
||||
struct Error : virtual Exception {} ;
|
||||
typedef boost::error_info<struct JsonTag, Json> JsonInfo ;
|
||||
|
||||
public :
|
||||
template <typename T>
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
#include "DateTime.hh"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
@ -149,4 +151,11 @@ void DateTime::Swap( DateTime& dt )
|
|||
std::swap( m_nsec, dt.m_nsec ) ;
|
||||
}
|
||||
|
||||
std::string DateTime::ToString() const
|
||||
{
|
||||
std::ostringstream ss ;
|
||||
ss << *this ;
|
||||
return ss.str() ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
|
|
@ -51,6 +51,7 @@ public :
|
|||
bool operator<=( const DateTime& dt ) const ;
|
||||
|
||||
void Swap( DateTime& dt ) ;
|
||||
std::string ToString() const ;
|
||||
|
||||
private :
|
||||
std::time_t m_sec ;
|
||||
|
|
|
@ -92,7 +92,7 @@ public :
|
|||
|
||||
// cannot allow duplicate attribute nodes
|
||||
if ( child->m_type == attr && p.first != p.second )
|
||||
throw Error() << expt::ErrMsg( "duplicate attribute " + child->m_name ) ;
|
||||
BOOST_THROW_EXCEPTION( Error() << expt::ErrMsg( "duplicate attribute " + child->m_name ) ) ;
|
||||
|
||||
vec.insert( p.second, child ) ;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "util/DefaultLog.hh"
|
||||
|
||||
#include "drive/EntryTest.hh"
|
||||
#include "drive/ResourceTreeTest.hh"
|
||||
#include "drive/StateTest.hh"
|
||||
#include "util/DateTimeTest.hh"
|
||||
#include "util/FunctionTest.hh"
|
||||
|
@ -40,6 +41,7 @@ int main( int argc, char **argv )
|
|||
CppUnit::TextUi::TestRunner runner;
|
||||
runner.addTest( EntryTest::suite( ) ) ;
|
||||
runner.addTest( StateTest::suite( ) ) ;
|
||||
runner.addTest( ResourceTreeTest::suite( ) ) ;
|
||||
runner.addTest( DateTimeTest::suite( ) ) ;
|
||||
runner.addTest( FunctionTest::suite( ) ) ;
|
||||
runner.addTest( SignalHandlerTest::suite( ) ) ;
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2012 Wan Wai Ho
|
||||
|
||||
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 version 2
|
||||
of the License.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "ResourceTreeTest.hh"
|
||||
|
||||
#include "Assert.hh"
|
||||
|
||||
#include "drive/ResourceTree.hh"
|
||||
#include "drive/Resource.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace grut {
|
||||
|
||||
using namespace gr ;
|
||||
|
||||
ResourceTreeTest::ResourceTreeTest( )
|
||||
{
|
||||
}
|
||||
|
||||
void ResourceTreeTest::TestSerialize( )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // end of namespace grut
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
grive: an GPL program to sync a local directory with Google Drive
|
||||
Copyright (C) 2012 Wan Wai Ho
|
||||
|
||||
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 version 2
|
||||
of the License.
|
||||
|
||||
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
namespace grut {
|
||||
|
||||
class ResourceTreeTest : public CppUnit::TestFixture
|
||||
{
|
||||
public :
|
||||
ResourceTreeTest( ) ;
|
||||
|
||||
// declare suit function
|
||||
CPPUNIT_TEST_SUITE( ResourceTreeTest ) ;
|
||||
CPPUNIT_TEST( TestSerialize ) ;
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
private :
|
||||
void TestSerialize( ) ;
|
||||
} ;
|
||||
|
||||
} // end of namespace
|
Loading…
Reference in New Issue