/*************************************************************************** * test_GSupport.cpp - test support module * * ----------------------------------------------------------------------- * * copyright (C) 2010-2015 by Juergen Knoedlseder * * ----------------------------------------------------------------------- * * * * 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, either version 3 of the License, or * * (at your option) any later version. * * * * 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, see . * * * ***************************************************************************/ /** * @file test_GSupport.cpp * @brief Testing of support module * @author Juergen Knoedlseder */ /* __ Includes ___________________________________________________________ */ #ifdef HAVE_CONFIG_H #include #endif #include // getenv #include #include "GTools.hpp" #include "test_GSupport.hpp" /* __ Namespaces _________________________________________________________ */ /* __ Globals ____________________________________________________________ */ /* __ Debug definitions __________________________________________________ */ /***********************************************************************//** * @brief Set parameters and tests ***************************************************************************/ void TestGSupport::set(void){ // Set test name name("GSupport"); // Append tests append(static_cast(&TestGSupport::test_tools), "Test GTools"); append(static_cast(&TestGSupport::test_expand_env), "Test Environment variable"); append(static_cast(&TestGSupport::test_node_array), "Test GNodeArray"); append(static_cast(&TestGSupport::test_bilinear), "Test GBilinear"); append(static_cast(&TestGSupport::test_url_file), "Test GUrlFile"); append(static_cast(&TestGSupport::test_url_string), "Test GUrlString"); // Return return; } /***********************************************************************//** * @brief Clone test suite * * @return Pointer to deep copy of test suite. ***************************************************************************/ TestGSupport* TestGSupport::clone(void) const { // Clone test suite return new TestGSupport(*this); } /***********************************************************************//** * @brief Test GTools * * Test the GTools functions ***************************************************************************/ void TestGSupport::test_tools(void) { // Test XML to string conversion std::string s_in = "Hallo World, you \"are\" my 'nice' & place"; std::string s_ref = "Hallo World, you "are" my 'nice'" " <planet> & place"; std::string s_out; s_out = gammalib::str2xml(s_in); test_assert(s_out == s_ref, "gammalib::str2xml()", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); s_out = gammalib::xml2str(s_out); test_assert(s_out == s_in, "gammalib::str2xml()", "Unexpected string \""+s_out+"\" (expected \""+s_in+"\")"); // Test power law flux computations test_value(gammalib::plaw_energy_flux(2.0, 3.0, 2.5, -1.0), 2.5); test_value(gammalib::plaw_energy_flux(2.0, 3.0, 2.5, -2.5), 2.56453824468); test_value(gammalib::plaw_photon_flux(2.0, 3.0, 2.5, -1.0), 1.01366277027); test_value(gammalib::plaw_photon_flux(2.0, 3.0, 2.5, -2.5), 1.06136118604); // Return return; } /***********************************************************************//** * @brief Test expand_env function * * Test the environment variable expansion function. ***************************************************************************/ void TestGSupport::test_expand_env(void) { // Declare strings that we use during the tests std::string s_in; std::string s_ref; std::string s_out; // Test 1: no environment variable s_in = "This string has no environment variable."; s_ref = s_in; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"no environment variable", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Get home environment variable std::string home(std::getenv("HOME")); // $ENV{HOME} environment variable within string s_in = "My $ENV{HOME} is my castle."; s_ref = "My "+home+" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$ENV{HOME} environment variable within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // ${HOME} environment variable within string s_in = "My ${HOME} is my castle."; s_ref = "My "+home+" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"${HOME} environment variable within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $HOME/path environment variable within string s_in = "My $HOME/path is my castle."; s_ref = "My "+home+"/path is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$HOME/path environment variable within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $HOME environment variable at end of string s_in = "My $HOME"; s_ref = "My "+home; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$HOME environment variable at end of string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Environment variable within single quotes s_in = "My '$(HOME)' is my castle."; s_ref = s_in; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"Environment variable within single quotes", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Environment variable within double quotes s_in = "My \"$(HOME)\" is my castle."; s_ref = "My \""+home+"\" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"Environment variable within double quotes", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Non existing environment variable within string s_in = "My $(HOMEIXYZ) is my castle."; s_ref = "My is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"Non existing environment variable within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Empty environment variable within string s_in = "My $() is my castle."; s_ref = "My is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"Empty environment variable within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Two successive environment variables within string s_in = "My $(HOME)$ENV{HOME} is my castle."; s_ref = "My "+home+home+" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"Two successive environment variables within string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $(HOME) at beginning of string s_in = "$(HOME) is my castle."; s_ref = home+" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$(HOME) at beginning of string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $ENV(HOME) at beginning of string s_in = "$ENV(HOME) is my castle."; s_ref = home+" is my castle."; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$ENV(HOME) at beginning of string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $(HOME) at end of string s_in = "My castle is $(HOME)"; s_ref = "My castle is "+home; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$(HOME) at end of string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // $ENV{HOME}${HOME}$ENV(HOME)$(HOME) only string s_in = "$ENV{HOME}${HOME}$ENV(HOME)$(HOME)"; s_ref = home+home+home+home; s_out = gammalib::expand_env(s_in); test_assert(s_out == s_ref,"$ENV{HOME}${HOME}$ENV(HOME)$(HOME) only string", "Unexpected string \""+s_out+"\" (expected \""+s_ref+"\")"); // Debugging //std::cout << std::endl; //std::cout << s_in << std::endl; //std::cout << s_ref << std::endl; //std::cout << s_out << std::endl; // Exit test return; } /***********************************************************************//** * @brief Test GNodeArray class * * Test the GNodeArray class. ***************************************************************************/ void TestGSupport::test_node_array(void) { // Test void constructor test_try("Void constructor"); try { GNodeArray array; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test copy constructor test_try("Copy constructor"); try { GNodeArray array; GNodeArray array2(array); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test array constructor test_try("Array constructor"); try { double array[] = {0.0, 1.0, 2.0, 3.0, 5.0}; GNodeArray array2(5, array); test_try_success(); for (int i = 0; i < 5; ++i) { test_value(array2[i], array[i]); } } catch (std::exception &e) { test_try_failure(e); } // Test GVector constructor test_try("GVector constructor"); try { double array[] = {0.0, 1.0, 2.0, 3.0, 5.0}; GVector vector(5); for (int i = 0; i < 5; ++i) { vector[i] = array[i]; } GNodeArray array2(vector); test_try_success(); for (int i = 0; i < 5; ++i) { test_value(array2[i], vector[i]); } } catch (std::exception &e) { test_try_failure(e); } // Test std::vector constructor test_try("std::vector constructor"); try { double array[] = {0.0, 1.0, 2.0, 3.0, 5.0}; std::vector vector; for (int i = 0; i < 5; ++i) { vector.push_back(array[i]); } GNodeArray array2(vector); test_try_success(); for (int i = 0; i < 5; ++i) { test_value(array2[i], vector[i]); } } catch (std::exception &e) { test_try_failure(e); } // Test container manipulation test_try("Container manipulation"); try { GNodeArray array; test_assert(array.is_empty(), "Node array should be empty"); array.append(0.0); test_assert(!array.is_empty(), "Node array should not be empty"); test_value(array.size(), 1); array.append(1.0); array.append(2.0); array.append(3.0); array.append(5.0); test_value(array.size(), 5); array.insert(4, 4.0); test_value(array.size(), 6); for (int i = 0; i < array.size(); ++i) { test_value(array[i], double(i)); // 0, 1, 2, 3, 4, 5 } array.remove(1); array.remove(2); array.remove(3); test_value(array.size(), 3); for (int i = 0; i < array.size(); ++i) { test_value(array[i], double(2*i)); // 0, 2, 4 } GNodeArray array2; array2.append(6.0); array2.append(8.0); test_value(array2.size(), 2); array.extend(array2); test_value(array.size(), 5); for (int i = 0; i < array.size(); ++i) { test_value(array[i], double(2*i)); // 0, 2, 4, 6, 8 } test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test linear interpolation double array_lin[] = {-1.0, 0.0, 1.0}; test_node_array_interpolation(3, array_lin); // Test non-linear interpolation double array_nonlin[] = {-1.3, 0.0, 1.7}; test_node_array_interpolation(3, array_nonlin); // Test node array change using access operator[] GNodeArray nodes; nodes.append(1.0); nodes.append(2.0); nodes.append(3.0); nodes.set_value(2.5); test_value(nodes.inx_left(), 1, "Expected node 1"); test_value(nodes.inx_right(), 2, "Expected node 2"); test_value(nodes.wgt_left(), 0.5, 1.0e-6, "Expected weight 0.5"); test_value(nodes.wgt_right(), 0.5, 1.0e-6, "Expected weight 0.5"); nodes[1] = 3.0; nodes[2] = 4.0; nodes.set_value(2.5); test_value(nodes.inx_left(), 0, "Expected node 0"); test_value(nodes.inx_right(), 1, "Expected node 1"); test_value(nodes.wgt_left(), 0.25, 1.0e-6, "Expected weight 0.25"); test_value(nodes.wgt_right(), 0.75, 1.0e-6, "Expected weight 0.75"); // Return return; } /***********************************************************************//** * @brief Test GNodeArray class interpolation * * @param[in] num Number of nodes. * @param[in] nodes Nodes. * * Test the GNodeArray class interpolation method by comparing the * interpolation results for a linear function to the expected result. ***************************************************************************/ void TestGSupport::test_node_array_interpolation(const int& num, const double* nodes) { // Setup function parameters const double slope = 3.1; const double offset = 7.9; // Initialise node array GNodeArray array(num, nodes); // Setup node values std::vector values; for (int i = 0; i < 3; ++i) { values.push_back(nodes[i] * slope + offset); } // Test values for (double value = -2.0; value <= +2.0; value += 0.2) { double expected = value * slope + offset; double result = array.interpolate(value, values); test_value(result, expected); } // Return return; } /***********************************************************************//** * @brief Test GBilinear class * * Test the GBilinear class. ***************************************************************************/ void TestGSupport::test_bilinear(void) { // Test constructor GBilinear interpolator; // Test value setting and retrieving interpolator.index1() = 1; interpolator.index2() = 2; interpolator.index3() = 3; interpolator.index4() = 4; interpolator.weight1() = 1.0; interpolator.weight2() = 2.0; interpolator.weight3() = 3.0; interpolator.weight4() = 4.0; test_value(interpolator.index1(), 1); test_value(interpolator.index2(), 2); test_value(interpolator.index3(), 3); test_value(interpolator.index4(), 4); test_value(interpolator.weight1(), 1.0); test_value(interpolator.weight2(), 2.0); test_value(interpolator.weight3(), 3.0); test_value(interpolator.weight4(), 4.0); // Test copy constructor GBilinear interpolator2(interpolator); test_value(interpolator2.index1(), 1); test_value(interpolator2.index2(), 2); test_value(interpolator2.index3(), 3); test_value(interpolator2.index4(), 4); test_value(interpolator2.weight1(), 1.0); test_value(interpolator2.weight2(), 2.0); test_value(interpolator2.weight3(), 3.0); test_value(interpolator2.weight4(), 4.0); // Test interpolator double array[5] = {1.0, 2.0, 3.0, 4.0, 5.0}; double reference = 1.0 * array[1] + 2.0 * array[2] + 3.0 * array[3] + 4.0 * array[4]; test_value(interpolator(array), reference); test_value(interpolator2(array), reference); // Return return; } /***********************************************************************//** * @brief Test GUrlFile class * * Test the GUrlFile class. ***************************************************************************/ void TestGSupport::test_url_file(void) { // Test void constructor test_try("Void constructor"); try { GUrlFile url; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test open constructor test_try("Open constructor"); try { GUrlFile url("test_url.dat", "w"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test file writing GUrlFile url("test_url.dat", "w"); test_value(url.write("abcd", 4), 4); url.put_char('e'); url.printf("fghi%s%d%3.1fxyz", "jklm", 41, 9.9); url.close(); // Test file reading using read() method char buffer[100]; url.open("test_url.dat", "r"); test_value(url.read(buffer, 99), 21); std::string result = std::string(buffer, 21); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); url.close(); // Test file reading using get_char() method result.clear(); url.open("test_url.dat", "r"); int character = 0; do { character = url.get_char(); if (character != EOF) { char c = (char)character; result.append(1, c); } } while (character != EOF); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); url.close(); // Test file reading using scanf() method result.clear(); url.open("test_url.dat", "r"); url.scanf("%99s", buffer); result = std::string(buffer, 21); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); url.close(); // Return return; } /***********************************************************************//** * @brief Test GUrlString class * * Test the GUrlString class. ***************************************************************************/ void TestGSupport::test_url_string(void) { // Test void constructor test_try("Void constructor"); try { GUrlString url; test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test open constructor test_try("Open constructor"); try { GUrlString url("My nice text string"); test_try_success(); } catch (std::exception &e) { test_try_failure(e); } // Test string writing GUrlString url; test_value(url.write("abcd", 4), 4); url.put_char('e'); url.printf("fghi%s%d%3.1fxyz", "jklm", 41, 9.9); // Test string reading using read() method char buffer[100]; url.rewind(); test_value(url.read(buffer, 99), 21); std::string result = std::string(buffer, 21); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); // Test string reading using get_char() method result.clear(); url.rewind(); int character = 0; do { character = url.get_char(); if (character != EOF) { char c = (char)character; result.append(1, c); } } while (character != EOF); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); // Test string reading using scanf() method char buffer2[100]; result.clear(); url.rewind(); url.scanf("%99s", buffer2); result = std::string(buffer2, 21); test_assert(result.compare("abcdefghijklm419.9xyz") == 0, "Expected \"abcdefghijklm419.9xyz\" in file, found \""+ result+"\n"); url.close(); // Return return; } /***********************************************************************//** * @brief Main test entry point ***************************************************************************/ int main(void) { // Allocate test suite container GTestSuites testsuites("Support module"); // Initially assume that we pass all tests bool success = true; // Create and append test suite TestGSupport test; testsuites.append(test); // Run the testsuites success = testsuites.run(); // Save test report testsuites.save("reports/GSupport.xml"); // Return success status return (success ? 0 : 1); }