Skip to content

Commit

Permalink
add an ascii serialization test for all objects
Browse files Browse the repository at this point in the history
  • Loading branch information
karlnapf committed Jan 26, 2018
1 parent 7cfc4b6 commit d35b26b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/shogun/base/SGObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,3 +1004,8 @@ bool CSGObject::equals(const CSGObject* other) const
SG_SDEBUG("All parameters of %s equal.\n", this->get_name());
return true;
}

CSGObject* CSGObject::create_empty() const
{
CSGObject* object = create(this->get_name(), this->m_generic);
}
19 changes: 19 additions & 0 deletions src/shogun/base/SGObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ class CSGObject
*/
template<class T> void set_generic();

/** Returns generic type.
* @return generic type of this object
*/
EPrimitiveType get_generic() const
{
return m_generic;
}

/** unset generic type
*
* this has to be called in classes specializing a template class
Expand Down Expand Up @@ -581,6 +589,17 @@ class CSGObject
virtual CSGObject* clone();

protected:
/** Returns an empty instance of own type.
*
* When inheriting from CSGObject from outside the main source tree (i.e.
* customized classes, or in a unit test), then this method has to be
* overloaded manually to return an empty instance.
* Shogun can only instantiate empty class instances from its source tree.
*
* @return empty instance of own type
*/
virtual CSGObject* create_empty() const;

/** Iteratively clones all parameters of the provided instance into this instance.
* This will fail if the objects have different sets of registered parameters,
* or if they have a different type as defined by get_name().
Expand Down
16 changes: 15 additions & 1 deletion tests/unit/base/MockObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ namespace shogun

watch_param("some_value", &m_some_value);
}
const char* get_name() const
const char* get_name() const override
{
return "CloneEqualsMockParameter";
}

virtual CSGObject* create_empty() const override
{
CSGObject* empty = new CCloneEqualsMockParameter();
SG_REF(empty);
return empty;
}

virtual CSGObject* clone()
{
auto* clone = new CCloneEqualsMockParameter<T>();
Expand Down Expand Up @@ -187,6 +194,13 @@ namespace shogun
return "CloneEqualsMock";
}

virtual CSGObject* create_empty() const override
{
CSGObject* empty = new CCloneEqualsMock();
SG_REF(empty);
return empty;
}

T m_basic;
CCloneEqualsMockParameter<T>* m_object;

Expand Down
44 changes: 43 additions & 1 deletion tests/unit/base/SGObject_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

#include "MockObject.h"
#include "utils/Utils.h"
#include <iterator>
#include <shogun/base/class_list.h>
#include <shogun/base/some.h>
Expand Down Expand Up @@ -626,6 +627,7 @@ SG_PRIMITIVE_TYPE(float32_t, PT_FLOAT32);
SG_PRIMITIVE_TYPE(float64_t, PT_FLOAT64);
SG_PRIMITIVE_TYPE(floatmax_t, PT_FLOATMAX);
SG_PRIMITIVE_TYPE(untemplated_sgobject, PT_NOT_GENERIC);
#undef SG_PRIMITIVE_TYPE

/** Helper to write c++11 style loops in tests that cover all Shogun classes */
template <typename T>
Expand Down Expand Up @@ -753,6 +755,7 @@ TYPED_TEST(SGObjectAll, clone_basic)
{
for (auto obj : sg_object_iterator<TypeParam>(sg_object_all_ignores))
{
SCOPED_TRACE(obj->get_name());
CSGObject* clone = nullptr;
try
{
Expand All @@ -771,13 +774,52 @@ TYPED_TEST(SGObjectAll, clone_basic)
}
}

TYPED_TEST(SGObjectAll, clone_equals)
TYPED_TEST(SGObjectAll, clone_equals_empty)
{
for (auto obj : sg_object_iterator<TypeParam>(sg_object_all_ignores))
{
SCOPED_TRACE(obj->get_name());

CSGObject* clone = obj->clone();
EXPECT_TRUE(clone->equals(obj));

SG_UNREF(clone);
}
}

TYPED_TEST(SGObjectAll, serialization_empty_ascii)
{
for (auto obj : sg_object_iterator<TypeParam>(sg_object_all_ignores))
{
SCOPED_TRACE(obj->get_name());

std::string filename = "shogun-unittest-serialization-ascii-" +
std::string(obj->get_name()) + ".XXXXXX";
generate_temp_filename(const_cast<char*>(filename.c_str()));

CSerializableAsciiFile* file =
new CSerializableAsciiFile(filename.c_str(), 'w');
bool save_success = obj->save_serializable(file);
file->close();
SG_UNREF(file);
ASSERT_TRUE(save_success);

CSGObject* loaded = create(obj->get_name(), obj->get_generic());
ASSERT_NE(loaded, nullptr);
file = new CSerializableAsciiFile(filename.c_str(), 'r');
bool load_success = loaded->load_serializable(file);
file->close();
SG_UNREF(file);
ASSERT_TRUE(load_success);

// set accuracy to tolerate lossy formats
set_global_fequals_epsilon(1e-14);
ASSERT_TRUE(obj->equals(loaded));
set_global_fequals_epsilon(0);

SG_UNREF(loaded);

int delete_success = unlink(filename.c_str());
ASSERT_EQ(0, delete_success);
}
}

0 comments on commit d35b26b

Please sign in to comment.