#include "happly.h" #include #include #include #include #include "gtest/gtest.h" using std::cout; using std::endl; // === Test helpers void DoubleArrayVecEq(std::vector>& arr1, std::vector>& arr2) { EXPECT_EQ(arr1.size(), arr2.size()); for (size_t i = 0; i < arr1.size(); i++) { for (int j = 0; j < 3; j++) { EXPECT_DOUBLE_EQ(arr1[i][j], arr2[i][j]); } } } // void VecEq(std::vector& arr1, std::vector& arr2) { // EXPECT_EQ(arr1.size(), arr2.size()); // for (size_t i = 0; i < arr1.size(); i++) { // EXPECT_DOUBLE_EQ(arr1[i], arr2[i]); //} //} // == Test typed reading/writing // = char TEST(TypedReadWriteTest, ReadWriteCharASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 11, -12, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteCharBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 11, -12, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteCharBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 11, -12, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned char TEST(TypedReadWriteTest, ReadWriteUCharASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 255, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteUCharBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 255, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteUCharBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 255, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = short TEST(TypedReadWriteTest, ReadWriteShortASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 32767, -32768, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteShortBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 32767, -32768, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteShortBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 4, 32767, -32768, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned short TEST(TypedReadWriteTest, ReadWriteUShortASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 65535, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteUShortBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 65535, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteUShortBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 11, 65535, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = int TEST(TypedReadWriteTest, ReadWriteIntASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 0, 2147483647, -2147483647 - 1, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteIntBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 0, 2147483647, -2147483647 - 1, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteIntBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{-3, 0, 2147483647, -2147483647 - 1, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned int TEST(TypedReadWriteTest, ReadWriteUIntASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 4294967295, 15, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteUIntBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 4294967295, 15, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteUIntBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector testData{3, 0, 4294967295, 15, 122}; plyOut.getElement("test_elem").addProperty("test_data", testData); // Binary read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyInB("temp.ply"); std::vector testDataBinary = plyInB.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = float TEST(TypedReadWriteTest, ReadWriteFloatASCII) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), // std::numeric_limits::infinity(), // these DO NOT work right now, due to how ostream works //-std::numeric_limits::infinity(), 0.0f, -0.0f, 1e24f, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteFloatBinary) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), std::numeric_limits::infinity(), -std::numeric_limits::infinity(), 0.0f, -0.0f, 1e24f, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector testDataBinary = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteFloatBinarySwap) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), std::numeric_limits::infinity(), -std::numeric_limits::infinity(), 0.0f, -0.0f, 1e24f, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector testDataBinary = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = double TEST(TypedReadWriteTest, ReadWriteDoubleASCII) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), // std::numeric_limits::infinity(), // these DO NOT work right now, due to how ostream works //-std::numeric_limits::infinity(), 0.0, -0.0, 1e24, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector testDataASCII = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedReadWriteTest, ReadWriteDoubleBinary) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), std::numeric_limits::infinity(), -std::numeric_limits::infinity(), 0.0, -0.0, 1e24, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector testDataBinary = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedReadWriteTest, ReadWriteDoubleBinarySwap) { // Create a simple file happly::PLYData plyOut; std::vector testData{ 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), std::numeric_limits::infinity(), -std::numeric_limits::infinity(), 0.0, -0.0, 1e24, }; plyOut.addElement("test_elem", testData.size()); plyOut.getElement("test_elem").addProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector testDataBinary = plyIn.getElement("test_elem").getProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = signed char list TEST(TypedListReadWriteTest, ReadWriteCharASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, -128, 127}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteCharBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, -128, 127}, {}, {}, {3, 11}, }; std::cout << "size: " << testData.size() << std::endl; for(auto& v : testData) { std::cout << "sub size: " << v.size() << std::endl; } plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); std::cout << "size: " << testDataBinary.size() << std::endl; for(auto& v : testDataBinary) { std::cout << "sub size: " << v.size() << std::endl; } EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteCharBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, -128, 127}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned char list TEST(TypedListReadWriteTest, ReadWriteUCharASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 255, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteUCharBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 255, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteUCharBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 255, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = signed short list TEST(TypedListReadWriteTest, ReadWriteShortASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 4, 32767, -32768, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteShortBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 4, 32767, -32768, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteShortBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 4, 32767, -32768, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned short list TEST(TypedListReadWriteTest, ReadWriteUShortASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 65535, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteUShortBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 65535, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteUShortBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 11, 65535, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = signed int list TEST(TypedListReadWriteTest, ReadWriteIntASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 0, 2147483647, -2147483647 - 1, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteIntBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 0, 2147483647, -2147483647 - 1, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteIntBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {-3, 0, 2147483647, -2147483647 - 1, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = unsigned int list TEST(TypedListReadWriteTest, ReadWriteUIntASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 4294967295, 15, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteUIntBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 4294967295, 15, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteUIntBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3}, {3, 0, 4294967295, 15, 122}, {}, {}, {3, 11}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = float list TEST(TypedListReadWriteTest, ReadWriteFloatASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3.f, 14.44f, 42.4242f}, { 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0f, -0.0f, 1e24f, }, {}, {1.1f}, {-121.5f, 1.111f}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteFloatBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3.f, 14.44f, 42.4242f}, { 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0f, -0.0f, 1e24f, }, {}, {1.1f}, {-121.5f, 1.111f}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteFloatBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3.f, 14.44f, 42.4242f}, { 3.141592653589793238f, -3.141592653589793238f, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0f, -0.0f, 1e24f, }, {}, {1.1f}, {-121.5f, 1.111f}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // = double list TEST(TypedListReadWriteTest, ReadWriteDoubleASCII) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3., 14.44, 42.4242}, { 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0, -0.0, 1e24, }, {}, {1.1}, {-121.5, 1.111}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::ASCII); happly::PLYData plyIn("temp.ply"); std::vector> testDataASCII = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataASCII); } TEST(TypedListReadWriteTest, ReadWriteDoubleBinary) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3., 14.44, 42.4242}, { 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0, -0.0, 1e24, }, {}, {1.1}, {-121.5, 1.111}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::Binary); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } TEST(TypedListReadWriteTest, ReadWriteDoubleBinarySwap) { // Create a simple file happly::PLYData plyOut; plyOut.addElement("test_elem", 5); std::vector> testData{ {3., 14.44, 42.4242}, { 3.141592653589793238, -3.141592653589793238, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::lowest(), std::numeric_limits::epsilon(), 0.0, -0.0, 1e24, }, {}, {1.1}, {-121.5, 1.111}, }; plyOut.getElement("test_elem").addListProperty("test_data", testData); // ASCII read/write plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); happly::PLYData plyIn("temp.ply"); std::vector> testDataBinary = plyIn.getElement("test_elem").getListProperty("test_data"); EXPECT_EQ(testData, testDataBinary); } // === Test error and utility behavior // Errors get thrown TEST(ErrorTest, NonexistantElement) { happly::PLYData emptyPly; EXPECT_THROW(emptyPly.getElement("test_elem");, std::runtime_error); } TEST(ErrorTest, NonexistantProperty) { happly::PLYData emptyPly; emptyPly.addElement("test_elem", 11); EXPECT_THROW(emptyPly.getElement("test_elem").getProperty("test_prop");, std::runtime_error); } TEST(ErrorTest, WrongSize) { happly::PLYData emptyPly; emptyPly.addElement("test_elem", 11); std::vector data{1, 3, 4}; EXPECT_THROW(emptyPly.getElement("test_elem").addProperty("bad_prop", data), std::runtime_error); } TEST(ErrorTest, WrongSizeList) { happly::PLYData emptyPly; emptyPly.addElement("test_elem", 11); std::vector> data{{1}, {3}, {4, 4}}; EXPECT_THROW(emptyPly.getElement("test_elem").addListProperty("bad_prop", data), std::runtime_error); } TEST(ErrorTest, WhiteSpaceInElementName) { happly::PLYData ply; ply.addElement("test elem", 11); EXPECT_THROW(ply.validate(), std::runtime_error); } TEST(ErrorTest, WhiteSpaceInPropertyName) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector data{1, 3, 4}; ply.getElement("test_elem").addProperty("test prop", data); EXPECT_THROW(ply.validate(), std::runtime_error); } // Removal TEST(RemovalTest, RemoveReplaceTest) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector data{1, 3, 4}; ply.getElement("test_elem").addProperty("data", data); EXPECT_EQ(data, ply.getElement("test_elem").getProperty("data")); // Replace with new std::vector data2{5, 5, 5}; ply.getElement("test_elem").addProperty("data", data2); EXPECT_EQ(data2, ply.getElement("test_elem").getProperty("data")); } // Type promotion TEST(TypePromotionTest, PromoteFloatToDouble) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector dataF{1.0, 3.0, 4.0}; std::vector dataD{1.0, 3.0, 4.0}; ply.getElement("test_elem").addProperty("data", dataF); EXPECT_EQ(dataD, ply.getElement("test_elem").getProperty("data")); } TEST(TypePromotionTest, DontPromoteDoubleToFloat) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector dataF{1.0, 3.0, 4.0}; std::vector dataD{1.0, 3.0, 4.0}; ply.getElement("test_elem").addProperty("data", dataD); EXPECT_THROW(ply.getElement("test_elem").getProperty("data"), std::runtime_error); } TEST(TypePromotionTest, PromoteUnsigned) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector dataC{1, 3, 5}; ply.getElement("test_elem").addProperty("data", dataC); std::vector dataS{1, 3, 5}; std::vector dataI{1, 3, 5}; std::vector dataL{1, 3, 5}; std::vector dataSZ{1, 3, 5}; EXPECT_EQ(dataC, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataS, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataI, ply.getElement("test_elem").getProperty("data")); //EXPECT_EQ(dataL, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataSZ, ply.getElement("test_elem").getProperty("data")); } TEST(TypePromotionTest, PromoteSigned) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector data{1, -3, 5}; ply.getElement("test_elem").addProperty("data", data); std::vector dataC{1, -3, 5}; std::vector dataS{1, -3, 5}; std::vector dataI{1, -3, 5}; std::vector dataL{1, -3, 5}; std::vector data64{1, -3, 5}; EXPECT_EQ(dataC, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataS, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataS, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataI, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(dataI, ply.getElement("test_elem").getProperty("data")); //EXPECT_EQ(dataL, ply.getElement("test_elem").getProperty("data")); EXPECT_EQ(data64, ply.getElement("test_elem").getProperty("data")); } TEST(TypePromotionTest, DontPromoteAcrossSign) { happly::PLYData ply; ply.addElement("test_elem", 3); std::vector dataI{1, -3, 5}; std::vector dataUI{1, 3, 5}; ply.getElement("test_elem").addProperty("dataI", dataI); ply.getElement("test_elem").addProperty("dataUI", dataUI); // Make sure data is there EXPECT_EQ(dataI, ply.getElement("test_elem").getProperty("dataI")); EXPECT_EQ(dataUI, ply.getElement("test_elem").getProperty("dataUI")); // But throws if we cross signedness EXPECT_THROW(ply.getElement("test_elem").getProperty("dataUI"), std::runtime_error); EXPECT_THROW(ply.getElement("test_elem").getProperty("dataI"), std::runtime_error); } TEST(TypePromotionTest, PromoteFaceInd) { happly::PLYData ply; ply.addElement("face", 3); std::vector> faceInds{{1, 3, 4}, {0, 2, 4, 5}, {1, 1, 1}}; std::vector> faceIndsS{{1, 3, 4}, {0, 2, 4, 5}, {1, 1, 1}}; ply.getElement("face").addListProperty("vertex_indices", faceInds); std::vector> faceIndGet = ply.getFaceIndices(); EXPECT_EQ(faceIndsS, faceIndGet); } TEST(TypePromotionTest, FaceIndSign) { happly::PLYData ply; ply.addElement("face", 3); std::vector> faceInds{{1, 3, 4}, {0, -2, 4, 5}, {1, 1, 1}}; std::vector> faceIndsI{{1, 3, 4}, {0, -2, 4, 5}, {1, 1, 1}}; std::vector> faceIndsU{{1, 3, 4}, {0, 2, 4, 5}, {1, 1, 1}}; ply.getElement("face").addListProperty("vertex_indices", faceInds); std::vector> faceIndGetI = ply.getFaceIndices(); EXPECT_EQ(faceIndsI, faceIndGetI); std::vector> faceIndGetU = ply.getFaceIndices(); EXPECT_NE(faceIndsU, faceIndGetU); } TEST(TypePromotionTest, FaceIndThrow) { happly::PLYData ply; ply.addElement("face", 3); std::vector> faceInds{{1, 3, 1LL << 40}, {0, 2, 4, 5}, {1, 1, 1}}; EXPECT_THROW(ply.getElement("face").addListProperty("vertex_indices", faceInds), std::runtime_error); } // === Test reading mesh-like files TEST(MeshTest, ReadWriteASCIIMesh) { // = Read in an interesting mesh file happly::PLYData plyIn("../sampledata/platonic_shelf_ascii.ply", false); plyIn.validate(); std::vector> vPos = plyIn.getVertexPositions(); std::vector> fInd = plyIn.getFaceIndices(); // = Write out the mesh file happly::PLYData plyOut; plyOut.addVertexPositions(vPos); plyOut.addFaceIndices(fInd); plyOut.validate(); plyOut.write("temp.ply"); // = Read the mesh file in again and make sure it hasn't changed happly::PLYData plyIn2("temp.ply", false); plyIn2.validate(); std::vector> vPos2 = plyIn2.getVertexPositions(); std::vector> fInd2 = plyIn2.getFaceIndices(); DoubleArrayVecEq(vPos, vPos2); EXPECT_EQ(fInd, fInd2); } TEST(MeshTest, ReadWriteBinaryMesh) { // = Read in an interesting mesh file happly::PLYData plyIn("../sampledata/platonic_shelf.ply", false); plyIn.validate(); std::vector> vPos = plyIn.getVertexPositions(); std::vector> fInd = plyIn.getFaceIndices(); // = Write out the mesh file happly::PLYData plyOut; plyOut.addVertexPositions(vPos); plyOut.addFaceIndices(fInd); plyOut.validate(); plyOut.write("temp.ply", happly::DataFormat::Binary); // = Read the mesh file in again and make sure it hasn't changed happly::PLYData plyIn2("temp.ply", false); plyIn2.validate(); std::vector> vPos2 = plyIn2.getVertexPositions(); std::vector> fInd2 = plyIn2.getFaceIndices(); DoubleArrayVecEq(vPos, vPos2); EXPECT_EQ(fInd, fInd2); } TEST(MeshTest, ReadWriteBinarySwapMesh) { // = Read in an interesting mesh file happly::PLYData plyIn("../sampledata/platonic_shelf_big_endian.ply", false); plyIn.validate(); std::vector> vPos = plyIn.getVertexPositions(); std::vector> fInd = plyIn.getFaceIndices(); // = Write out the mesh file happly::PLYData plyOut; plyOut.addVertexPositions(vPos); plyOut.addFaceIndices(fInd); plyOut.validate(); plyOut.write("temp.ply", happly::DataFormat::BinaryBigEndian); // = Read the mesh file in again and make sure it hasn't changed happly::PLYData plyIn2("temp.ply", false); plyIn2.validate(); std::vector> vPos2 = plyIn2.getVertexPositions(); std::vector> fInd2 = plyIn2.getFaceIndices(); DoubleArrayVecEq(vPos, vPos2); EXPECT_EQ(fInd, fInd2); } // === Test stream interfaces TEST(MeshTest, ReadWriteASCIIMeshStream) { // = Read the PLY from an input stream std::ifstream file ("../sampledata/platonic_shelf_ascii.ply"); happly::PLYData plyIn(file, false); plyIn.validate(); file.close(); std::vector> vPos = plyIn.getVertexPositions(); std::vector> fInd = plyIn.getFaceIndices(); // = Write the mesh file to a stringstream std::stringstream ioBuffer; happly::PLYData plyOut; plyOut.addVertexPositions(vPos); plyOut.addFaceIndices(fInd); plyOut.validate(); plyOut.write(ioBuffer); // = Read the mesh file in again and make sure it hasn't changed happly::PLYData plyIn2(ioBuffer, false); plyIn2.validate(); std::vector> vPos2 = plyIn2.getVertexPositions(); std::vector> fInd2 = plyIn2.getFaceIndices(); DoubleArrayVecEq(vPos, vPos2); EXPECT_EQ(fInd, fInd2); } TEST(MeshTest, ReadWriteBinaryMeshStream) { // = Read in an interesting mesh file std::ifstream file ("../sampledata/platonic_shelf_ascii.ply"); happly::PLYData plyIn(file, false); plyIn.validate(); file.close(); std::vector> vPos = plyIn.getVertexPositions(); std::vector> fInd = plyIn.getFaceIndices(); // = Write out the mesh to a stringstream std::stringstream ioBuffer; happly::PLYData plyOut; plyOut.addVertexPositions(vPos); plyOut.addFaceIndices(fInd); plyOut.validate(); plyOut.write(ioBuffer, happly::DataFormat::Binary); // = Read the mesh file in again and make sure it hasn't changed happly::PLYData plyIn2(ioBuffer, false); plyIn2.validate(); std::vector> vPos2 = plyIn2.getVertexPositions(); std::vector> fInd2 = plyIn2.getFaceIndices(); DoubleArrayVecEq(vPos, vPos2); EXPECT_EQ(fInd, fInd2); } TEST(PerfTest, WriteReadFloatList) { // Parameters size_t innerSizeMax = 10; size_t N = 100000; // Random number makers std::mt19937 gen(777); std::uniform_int_distribution distInnerSize(1, innerSizeMax); std::uniform_int_distribution distValues(0, 1000000); // Generate a long list of junk data std::vector> testVals; for (size_t i = 0; i < N; i++) { size_t innerCount = distInnerSize(gen); std::vector innerVals; for (size_t j = 0; j < innerCount; j++) { int val = distValues(gen); innerVals.push_back(val); } testVals.push_back(innerVals); } // Start timing auto tStart = std::chrono::steady_clock::now(); // Create a ply file happly::PLYData plyOut; plyOut.addElement("testElem", N); plyOut.getElement("testElem").addListProperty("testVals", testVals); // Write it to a stream std::stringstream ioBuffer; plyOut.write(ioBuffer, happly::DataFormat::Binary); // = Read from stream // (note that this DOES NOT actually access the property, but simply opening the stream parses everything) happly::PLYData plyIn(ioBuffer, false); // Finish timing auto tEnd = std::chrono::steady_clock::now(); std::cout << " time elapsed = " << std::chrono::duration_cast(tEnd - tStart).count() << "us" << std::endl; } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }