1667 lines
42 KiB
C++
1667 lines
42 KiB
C++
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
|
|
/*
|
|
* Copyright (c) 2019 Lawrence Livermore National Laboratory
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation;
|
|
*
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* Authors: Mathew Bielejeski<bielejeski1@llnl.gov>
|
|
*/
|
|
|
|
#include "ns3/length.h"
|
|
#include "ns3/log.h"
|
|
#include "ns3/object.h"
|
|
#include "ns3/string.h"
|
|
#include "ns3/test.h"
|
|
|
|
#ifdef HAVE_BOOST_UNITS
|
|
#include <boost/units/base_units/us/foot.hpp>
|
|
#include <boost/units/systems/si.hpp>
|
|
#include <boost/units/systems/si/prefixes.hpp>
|
|
#endif
|
|
|
|
#include <array>
|
|
#include <cmath>
|
|
#include <functional>
|
|
#include <initializer_list>
|
|
#include <iomanip>
|
|
#include <limits>
|
|
#include <map>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <tuple>
|
|
|
|
/**
|
|
* \file
|
|
* \ingroup core-tests
|
|
* \ingroup length
|
|
* \ingroup length-tests
|
|
* Length class test suite.
|
|
*/
|
|
|
|
/**
|
|
* \ingroup core-tests
|
|
* \defgroup length-tests Length test suite
|
|
*/
|
|
|
|
using namespace ns3;
|
|
|
|
/**
|
|
* Save some typing by defining a short alias for Length::Unit
|
|
*/
|
|
using Unit = Length::Unit;
|
|
|
|
/**
|
|
* Implements tests for the Length class
|
|
*/
|
|
class LengthTestCase : public TestCase
|
|
{
|
|
public:
|
|
/**
|
|
* Constructor
|
|
*/
|
|
LengthTestCase ()
|
|
: TestCase ("length-tests")
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~LengthTestCase () = default;
|
|
|
|
protected:
|
|
/**
|
|
* Helper function to compare results with false
|
|
*
|
|
* \param condition The boolean condition to test
|
|
* \param msg The message to print if the test fails
|
|
*/
|
|
void AssertFalse (bool condition, std::string msg)
|
|
{
|
|
NS_TEST_ASSERT_MSG_EQ (condition, false, msg);
|
|
}
|
|
|
|
/**
|
|
* Helper function to compare results with true
|
|
*
|
|
* \param condition The boolean condition to test
|
|
* \param msg The message to print if the test fails
|
|
*/
|
|
void AssertTrue (bool condition, std::string msg)
|
|
{
|
|
NS_TEST_ASSERT_MSG_EQ (condition, true, msg);
|
|
}
|
|
|
|
private:
|
|
/**
|
|
* Test that a default constructed Length object has a value of 0
|
|
*/
|
|
void TestDefaultLengthIsZero ();
|
|
|
|
/**
|
|
* Test that a Length object can be constructed from a Quantity object
|
|
*/
|
|
void TestConstructLengthFromQuantity ();
|
|
|
|
/**
|
|
* Test that a Length object constructed from various SI units has the
|
|
* correct value in meters
|
|
*/
|
|
void TestConstructLengthFromSIUnits ();
|
|
|
|
/**
|
|
* Test that a Length object constructed from various US units has the
|
|
* correct value in meters
|
|
*/
|
|
void TestConstructLengthFromUSUnits ();
|
|
|
|
/**
|
|
* Test that the value from one length is copied to another
|
|
* using the copy constructor.
|
|
*/
|
|
void TestLengthCopyConstructor ();
|
|
|
|
/**
|
|
* Test that the value from one length is copied to another
|
|
* using the move constructor.
|
|
*/
|
|
void TestLengthMoveConstructor ();
|
|
|
|
/**
|
|
* Test that a length object can be constructed from a string
|
|
* @{
|
|
*/
|
|
void TestConstructLengthFromString (double unitValue,
|
|
double meterValue,
|
|
double tolerance,
|
|
const std::initializer_list<std::string>& symbols);
|
|
|
|
void TestConstructLengthFromMeterString ();
|
|
void TestConstructLengthFromNanoMeterString ();
|
|
void TestConstructLengthFromMicroMeterString ();
|
|
void TestConstructLengthFromMilliMeterString ();
|
|
void TestConstructLengthFromCentiMeterString ();
|
|
void TestConstructLengthFromKiloMeterString ();
|
|
void TestConstructLengthFromNauticalMileString ();
|
|
void TestConstructLengthFromInchString ();
|
|
void TestConstructLengthFromFootString ();
|
|
void TestConstructLengthFromYardString ();
|
|
void TestConstructLengthFromMileString ();
|
|
/** @} */
|
|
|
|
#ifdef HAVE_BOOST_UNITS
|
|
/**
|
|
* Test construction from boost::units
|
|
* @{
|
|
*/
|
|
void TestConstructLengthFromBoostUnits ();
|
|
void TestConstructLengthFromBoostUnitsMeters ();
|
|
void TestConstructLengthFromBoostUnitsKiloMeters ();
|
|
void TestConstructLengthFromBoostUnitsFeet ();
|
|
/** @} */
|
|
#endif
|
|
|
|
/**
|
|
* Test constructing length objects using the builder free functions
|
|
* @{
|
|
*/
|
|
void TestBuilderFreeFunctions ();
|
|
/** @} */
|
|
|
|
/**
|
|
* Test the TryParse function returns false on bad input
|
|
*/
|
|
void TestTryParseReturnsFalse ();
|
|
|
|
/**
|
|
* Test the TryParse function returns true on success
|
|
*/
|
|
void TestTryParseReturnsTrue ();
|
|
|
|
|
|
/**
|
|
* Test that a length object can be updated by assignment from another
|
|
* length object
|
|
*/
|
|
void TestCopyAssignment ();
|
|
|
|
/**
|
|
* Test that a length object can be updated by assignment from a moved
|
|
* length object
|
|
*/
|
|
void TestMoveAssignment ();
|
|
|
|
/**
|
|
* Test that a length object can be updated by assignment from a quantity
|
|
*/
|
|
void TestQuantityAssignment ();
|
|
|
|
/**
|
|
* Test member comparison operators
|
|
* @{
|
|
*/
|
|
void TestIsEqualReturnsTrue ();
|
|
void TestIsEqualReturnsFalse ();
|
|
void TestIsEqualWithToleranceReturnsTrue ();
|
|
void TestIsEqualWithToleranceReturnsFalse ();
|
|
void TestIsNotEqualReturnsTrue ();
|
|
void TestIsNotEqualReturnsFalse ();
|
|
void TestIsNotEqualWithToleranceReturnsTrue ();
|
|
void TestIsNotEqualWithToleranceReturnsFalse ();
|
|
void TestIsLessReturnsTrue ();
|
|
void TestIsLessReturnsFalse ();
|
|
void TestIsLessWithToleranceReturnsFalse ();
|
|
void TestIsGreaterReturnsTrue ();
|
|
void TestIsGreaterReturnsFalse ();
|
|
void TestIsGreaterWithToleranceReturnsFalse ();
|
|
/** @} */
|
|
|
|
/**
|
|
* Test writing length object to a stream produces the expected output
|
|
*/
|
|
void TestOutputStreamOperator ();
|
|
|
|
/**
|
|
* Test reading length object from a stream produces the expected length
|
|
* value
|
|
*/
|
|
void TestInputStreamOperator ();
|
|
|
|
/**
|
|
* Generic function for testing serialization of a Length object in
|
|
* various units
|
|
*
|
|
* \tparam T Type of the length unit that should be output during serialization
|
|
*
|
|
* \param l Length object to serialize
|
|
* \param unit Unit that the length value will be converted to before serialization
|
|
* \param expectedOutput Expected result of the serialization
|
|
* \param context Included in the error message if the test fails
|
|
*/
|
|
template<class T>
|
|
void TestLengthSerialization (const Length& l,
|
|
const T& unit,
|
|
const std::string& expectedOutput,
|
|
const std::string& context);
|
|
|
|
/**
|
|
* Test serializing a length object to all of the supported unit types
|
|
*/
|
|
void TestSerializeLengthWithUnit ();
|
|
|
|
/**
|
|
* Test free function comparison operators
|
|
* @{
|
|
*/
|
|
void TestOperatorEqualsReturnsTrue ();
|
|
void TestOperatorEqualsReturnsFalse ();
|
|
void TestOperatorNotEqualsReturnsTrue ();
|
|
void TestOperatorNotEqualsReturnsFalse ();
|
|
void TestOperatorLessThanReturnsTrue ();
|
|
void TestOperatorLessThanReturnsFalse ();
|
|
void TestOperatorLessOrEqualReturnsTrue ();
|
|
void TestOperatorLessOrEqualReturnsFalse ();
|
|
void TestOperatorGreaterThanReturnsTrue ();
|
|
void TestOperatorGreaterThanReturnsFalse ();
|
|
void TestOperatorGreaterOrEqualReturnsTrue ();
|
|
void TestOperatorGreaterOrEqualReturnsFalse ();
|
|
/** @} */
|
|
|
|
/**
|
|
* Test arithmetic operations
|
|
* @{
|
|
*/
|
|
void TestAddingTwoLengths ();
|
|
void TestAddingLengthAndQuantity ();
|
|
void TestAddingQuantityAndLength ();
|
|
void TestSubtractingTwoLengths ();
|
|
void TestSubtractingLengthAndQuantity ();
|
|
void TestSubtractingQuantityAndLength ();
|
|
void TestMultiplyLengthByScalar ();
|
|
void TestMultiplyScalarByLength ();
|
|
void TestDivideLengthByScalar ();
|
|
void TestDivideLengthByLength ();
|
|
void TestDivideLengthByLengthReturnsNaN ();
|
|
/** @} */
|
|
|
|
/**
|
|
* Test Div function
|
|
* @{
|
|
*/
|
|
void TestDivReturnsCorrectResult ();
|
|
void TestDivReturnsZeroRemainder ();
|
|
void TestDivReturnsCorrectRemainder ();
|
|
/** @} */
|
|
|
|
/**
|
|
* Test Mod function
|
|
* @{
|
|
*/
|
|
void TestModReturnsZero ();
|
|
void TestModReturnsNonZero ();
|
|
/** @} */
|
|
|
|
virtual void DoRun ();
|
|
};
|
|
|
|
void
|
|
LengthTestCase::TestDefaultLengthIsZero ()
|
|
{
|
|
Length l;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), 0, "Default value of Length is not 0");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromQuantity ()
|
|
{
|
|
const Length::Quantity VALUE (5.0, Unit::Meter);
|
|
|
|
Length l (VALUE);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), VALUE.Value (),
|
|
"length constructed from meters has wrong value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromSIUnits ()
|
|
{
|
|
using TestEntry = std::tuple<Length, std::string>;
|
|
|
|
const double expectedMeters = 1;
|
|
const std::initializer_list<TestEntry> inputs {
|
|
std::make_tuple (Length (1e9, Unit::Nanometer), "nanometer"),
|
|
std::make_tuple (Length (1e6, Unit::Micrometer), "micrometer"),
|
|
std::make_tuple (Length (1e3, Unit::Millimeter), "millimeter"),
|
|
std::make_tuple (Length (1e2, Unit::Centimeter), "centimeter"),
|
|
std::make_tuple (Length (1e-3, Unit::Kilometer), "kilometer"),
|
|
std::make_tuple (Length ( (1 / 1852.0), Unit::NauticalMile), "nautical_mile")
|
|
};
|
|
|
|
for (const TestEntry& entry : inputs )
|
|
{
|
|
const Length& l = std::get<0> (entry);
|
|
const std::string& context = std::get<1> (entry);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), expectedMeters,
|
|
context << ": constructed length from SI unit has wrong value");
|
|
}
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromUSUnits ()
|
|
{
|
|
using TestEntry = std::tuple<Length, std::string>;
|
|
|
|
const double expectedMeters = 0.3048;
|
|
const double tolerance = 0.0001;
|
|
|
|
const std::initializer_list<TestEntry> inputs {
|
|
std::make_tuple (Length (12.0, Unit::Inch), "inch"),
|
|
std::make_tuple (Length (1.0, Unit::Foot), "foot"),
|
|
std::make_tuple (Length ((1 / 3.0), Unit::Yard), "yard"),
|
|
std::make_tuple (Length ((1 / 5280.0), Unit::Mile), "mile"),
|
|
};
|
|
|
|
for (const TestEntry& entry : inputs )
|
|
{
|
|
const Length& l = std::get<0> (entry);
|
|
const std::string& context = std::get<1> (entry);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedMeters, tolerance,
|
|
"constructed length from US unit (" << context << ") has wrong value");
|
|
}
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestLengthCopyConstructor ()
|
|
{
|
|
const double value = 5;
|
|
Length original (value, Unit::Meter);
|
|
|
|
Length copy (original);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), original.GetDouble (),
|
|
"copy constructed length has wrong value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestLengthMoveConstructor ()
|
|
{
|
|
const double value = 5;
|
|
Length original (value, Unit::Meter);
|
|
|
|
Length copy (std::move (original));
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
|
|
"move constructed length has wrong value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromString (double unitValue,
|
|
double meterValue,
|
|
double tolerance,
|
|
const std::initializer_list<std::string>& symbols)
|
|
{
|
|
const std::array<std::string, 2> SEPARATORS {{"", " "}};
|
|
|
|
for (const std::string& symbol : symbols)
|
|
{
|
|
for ( const std::string& separator : SEPARATORS )
|
|
{
|
|
std::ostringstream stream;
|
|
|
|
stream << unitValue << separator << symbol;
|
|
|
|
Length l (stream.str ());
|
|
|
|
std::ostringstream msg;
|
|
msg << "string constructed length has wrong value: '" << stream.str () << "'";
|
|
|
|
NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), meterValue, tolerance, msg.str ());
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromMeterString ()
|
|
{
|
|
const double value = 5;
|
|
|
|
TestConstructLengthFromString (value, value, 0,
|
|
{"m", "meter", "meters", "metre", "metres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromNanoMeterString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 5e-9;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, 0,
|
|
{"nm", "nanometer", "nanometers",
|
|
"nanometre", "nanometres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromMicroMeterString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 5e-6;
|
|
const double tolerance = 1e-7;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"um", "micrometer", "micrometers",
|
|
"micrometre", "micrometres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromMilliMeterString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 5e-3;
|
|
const double tolerance = 1e-4;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"mm", "millimeter", "millimeters",
|
|
"millimetre", "millimetres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromCentiMeterString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 5e-2;
|
|
const double tolerance = 1e-3;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"cm", "centimeter", "centimeters",
|
|
"centimetre", "centimetres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromKiloMeterString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 5e3;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, 0,
|
|
{"km", "kilometer", "kilometers",
|
|
"kilometre", "kilometres"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromNauticalMileString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 9260;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, 0,
|
|
{"nmi", "nautical mile", "nautical miles"});
|
|
}
|
|
void
|
|
LengthTestCase::TestConstructLengthFromInchString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 0.127;
|
|
const double tolerance = 1e-4;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"in", "inch", "inches"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromFootString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 1.524;
|
|
const double tolerance = 1e-4;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"ft", "foot", "feet"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromYardString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 4.572;
|
|
const double tolerance = 1e-4;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"yd", "yard", "yards"});
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromMileString ()
|
|
{
|
|
const double value = 5;
|
|
const double expectedValue = 8046.72;
|
|
const double tolerance = 1e-3;
|
|
|
|
TestConstructLengthFromString (value, expectedValue, tolerance,
|
|
{"mi", "mile", "miles"});
|
|
}
|
|
|
|
#ifdef HAVE_BOOST_UNITS
|
|
void
|
|
LengthTestCase::TestConstructLengthFromBoostUnits ()
|
|
{
|
|
TestConstructLengthFromBoostUnitsMeters ();
|
|
TestConstructLengthFromBoostUnitsKiloMeters ();
|
|
TestConstructLengthFromBoostUnitsFeet ();
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromBoostUnitsMeters ()
|
|
{
|
|
namespace bu = boost::units;
|
|
|
|
auto meters = 5 * bu::si::meter;
|
|
|
|
Length l (meters);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), meters.value (),
|
|
"Construction from boost::units meters produced "
|
|
"incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters ()
|
|
{
|
|
namespace bu = boost::units;
|
|
auto kilometer = bu::si::kilo * bu::si::meter;
|
|
|
|
const double expectedValue = 5000;
|
|
auto quantity = 5 * kilometer;
|
|
|
|
Length l (quantity);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), expectedValue,
|
|
"Construction from boost::units kilometers produced "
|
|
"incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestConstructLengthFromBoostUnitsFeet ()
|
|
{
|
|
namespace bu = boost::units;
|
|
|
|
bu::us::foot_base_unit::unit_type Foot;
|
|
|
|
const double expectedValue = 3.048;
|
|
auto feet = 10 * Foot;
|
|
|
|
Length l (feet);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedValue, 0.001,
|
|
"Construction from boost::units foot produced "
|
|
"incorrect value");
|
|
}
|
|
#endif
|
|
|
|
void
|
|
LengthTestCase::TestBuilderFreeFunctions ()
|
|
{
|
|
using Builder = std::function<Length (double)>;
|
|
|
|
double inputValue = 10;
|
|
|
|
std::map<Unit, Builder> TESTDATA{
|
|
{Unit::Nanometer, NanoMeters},
|
|
{Unit::Micrometer, MicroMeters},
|
|
{Unit::Millimeter, MilliMeters},
|
|
{Unit::Centimeter, CentiMeters},
|
|
{Unit::Meter, Meters},
|
|
{Unit::Kilometer, KiloMeters},
|
|
{Unit::NauticalMile, NauticalMiles},
|
|
{Unit::Inch, Inches},
|
|
{Unit::Foot, Feet},
|
|
{Unit::Yard, Yards},
|
|
{Unit::Mile, Miles}
|
|
};
|
|
|
|
for (auto& entry : TESTDATA)
|
|
{
|
|
Length expected (inputValue, entry.first);
|
|
|
|
Length output = entry.second (inputValue);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (output, expected,
|
|
"The builder free function for " << entry.first <<
|
|
" did not create a Length with the correct value");
|
|
}
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestTryParseReturnsFalse ()
|
|
{
|
|
bool result;
|
|
Length l;
|
|
|
|
std::tie (result, l) = Length::TryParse (1, "");
|
|
|
|
AssertFalse (result, "TryParse returned true on bad input");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestTryParseReturnsTrue ()
|
|
{
|
|
using TestInput = std::pair<double, std::string>;
|
|
using TestArgs = std::pair<double, double>;
|
|
std::map<TestInput, TestArgs> tests{
|
|
{{5, "m"}, {5, 0}},
|
|
{{5, " m"}, {5, 0}},
|
|
{{5, "kilometer"}, {5e3, 0}},
|
|
{{5, " kilometer"}, {5e3, 0}}
|
|
};
|
|
|
|
for (auto& entry : tests)
|
|
{
|
|
TestInput input = entry.first;
|
|
TestArgs args = entry.second;
|
|
|
|
bool result;
|
|
Length l;
|
|
|
|
std::tie (result, l) = Length::TryParse (input.first, input.second);
|
|
|
|
AssertTrue (result, "TryParse returned false when expecting true");
|
|
|
|
std::stringstream stream;
|
|
stream << "Parsing input (" << input.first << ", " << input.second
|
|
<< ") returned the wrong value";
|
|
|
|
NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), args.first, args.second, stream.str ());
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestCopyAssignment ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length original (value, Unit::Meter);
|
|
|
|
Length copy;
|
|
copy = original;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), original.GetDouble (),
|
|
"copy assignment failed");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestMoveAssignment ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length original (value, Unit::Meter);
|
|
|
|
Length copy;
|
|
copy = std::move (original);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
|
|
"move assignment failed");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestQuantityAssignment ()
|
|
{
|
|
Length::Quantity input (5, Unit::Kilometer);
|
|
|
|
Length l;
|
|
Length expected (input);
|
|
|
|
l = input;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l, expected,
|
|
"quantity assignment failed");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsEqualReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
Length one (value, Unit::Meter);
|
|
Length two (one);
|
|
|
|
AssertTrue (one.IsEqual (two), "IsEqual returned false for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsEqualReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
Length one (value, Unit::Meter);
|
|
Length two ( value, Unit::Foot );
|
|
|
|
AssertFalse (one.IsEqual (two), "IsEqual returned true for unequal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsEqualWithToleranceReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
const double tolerance = 0.1;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( (value + 0.1), Unit::Meter);
|
|
|
|
AssertTrue (one.IsEqual (two, tolerance),
|
|
"IsEqual returned false for almost equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsEqualWithToleranceReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
const double tolerance = 0.01;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( (value + 0.1), Unit::Meter);
|
|
|
|
AssertFalse (one.IsEqual (two, tolerance),
|
|
"IsEqual returned true for almost equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsNotEqualReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( (value + 0.1), Unit::Meter);
|
|
|
|
AssertTrue (one.IsNotEqual (two),
|
|
"IsNotEqual returned false for not equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsNotEqualReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( one );
|
|
|
|
AssertFalse (one.IsNotEqual (two),
|
|
"IsNotEqual returned true for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsNotEqualWithToleranceReturnsTrue ()
|
|
{
|
|
const double tolerance = 0.001;
|
|
|
|
Length one ( 5.01, Unit::Meter);
|
|
Length two ( 5.02, Unit::Meter);
|
|
|
|
AssertTrue (one.IsNotEqual (two, tolerance),
|
|
"IsNotEqual with tolerance returned false for not equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsNotEqualWithToleranceReturnsFalse ()
|
|
{
|
|
const double tolerance = 0.01;
|
|
|
|
Length one ( 5.01, Unit::Meter);
|
|
Length two ( 5.02, Unit::Meter);
|
|
|
|
AssertFalse (one.IsNotEqual (two, tolerance),
|
|
"IsNotEqual with tolerance returned true for not equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsLessReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( (value + 0.1), Unit::Meter);
|
|
|
|
AssertTrue (one.IsLess (two),
|
|
"IsLess returned false for non equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsLessReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one (value, Unit::Meter);
|
|
Length two ( one );
|
|
|
|
AssertFalse (one.IsLess (two),
|
|
"IsLess returned true for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsLessWithToleranceReturnsFalse ()
|
|
{
|
|
const double tolerance = 0.01;
|
|
|
|
Length one ( 5.1234, Unit::Meter );
|
|
Length two ( 5.1278, Unit::Meter );
|
|
|
|
AssertFalse (one.IsLess (two, tolerance),
|
|
"IsLess with tolerance returned true");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsGreaterReturnsTrue ()
|
|
{
|
|
Length one (2.0, Unit::Meter);
|
|
Length two (1.0, Unit::Meter);
|
|
|
|
AssertTrue (one.IsGreater (two),
|
|
"IsGreater returned false");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsGreaterReturnsFalse ()
|
|
{
|
|
Length one (2.0, Unit::Meter);
|
|
Length two (1.0, Unit::Meter);
|
|
|
|
AssertFalse (two.IsGreater (one),
|
|
"IsGreater returned true");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestIsGreaterWithToleranceReturnsFalse ()
|
|
{
|
|
const double tolerance = 0.01;
|
|
|
|
Length one (5.1234, Unit::Meter);
|
|
Length two (5.1278, Unit::Meter);
|
|
|
|
AssertFalse (two.IsGreater (one, tolerance),
|
|
"IsGreater returned true");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOutputStreamOperator ()
|
|
{
|
|
Length l (1.0, Unit::Meter);
|
|
|
|
std::stringstream stream;
|
|
|
|
stream << l;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (stream.str (), "1 m",
|
|
"unexpected output from operator<<");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestInputStreamOperator ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length l;
|
|
|
|
std::stringstream stream;
|
|
|
|
stream << value << "m";
|
|
|
|
stream >> l;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), value,
|
|
"unexpected length from operator>>");
|
|
}
|
|
|
|
template<class T>
|
|
void
|
|
LengthTestCase::TestLengthSerialization (const Length& l,
|
|
const T& unit,
|
|
const std::string& expectedOutput,
|
|
const std::string& context)
|
|
{
|
|
const std::string msg = context + ": unexpected output when serializing length";
|
|
|
|
std::ostringstream stream;
|
|
|
|
stream << std::fixed
|
|
<< std::setprecision (5)
|
|
<< l.As (unit);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (stream.str (), expectedOutput, msg);
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestSerializeLengthWithUnit ()
|
|
{
|
|
Length l (1.0, Unit::Meter);
|
|
|
|
TestLengthSerialization (l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
|
|
TestLengthSerialization (l, Unit::Micrometer, "1000000.00000 um", "micrometers");
|
|
TestLengthSerialization (l, Unit::Millimeter, "1000.00000 mm", "millimeters");
|
|
TestLengthSerialization (l, Unit::Centimeter, "100.00000 cm", "centimeters");
|
|
TestLengthSerialization (l, Unit::Meter, "1.00000 m", "meters");
|
|
TestLengthSerialization (l, Unit::Kilometer, "0.00100 km", "kilometers");
|
|
TestLengthSerialization (l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
|
|
TestLengthSerialization (l, Unit::Inch, "39.37008 in", "inches");
|
|
TestLengthSerialization (l, Unit::Foot, "3.28084 ft", "feet");
|
|
TestLengthSerialization (l, Unit::Yard, "1.09361 yd", "yards");
|
|
TestLengthSerialization (l, Unit::Mile, "0.00062 mi", "miles");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorEqualsReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Meter );
|
|
|
|
AssertTrue ( one == two,
|
|
"operator== returned false for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorEqualsReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer );
|
|
|
|
AssertFalse ( one == two,
|
|
"operator== returned true for non equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorNotEqualsReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertTrue ( one != two,
|
|
"operator!= returned false for non equal lengths");
|
|
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorNotEqualsReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Meter );
|
|
|
|
AssertFalse ( one != two,
|
|
"operator!= returned true for equal lengths");
|
|
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorLessThanReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertTrue ( one < two,
|
|
"operator< returned false for smaller length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorLessThanReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertFalse ( two < one,
|
|
"operator< returned true for larger length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorLessOrEqualReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
Length three ( one );
|
|
|
|
AssertTrue ( one <= two,
|
|
"operator<= returned false for smaller length");
|
|
|
|
AssertTrue ( one <= three,
|
|
"operator<= returned false for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorLessOrEqualReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertFalse ( two <= one,
|
|
"operator<= returned true for larger length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorGreaterThanReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertTrue ( two > one,
|
|
"operator> returned false for larger length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorGreaterThanReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertFalse ( one > two,
|
|
"operator> returned true for smaller length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorGreaterOrEqualReturnsTrue ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
Length three ( one );
|
|
|
|
AssertTrue ( two >= one,
|
|
"operator>= returned false for larger length");
|
|
|
|
AssertTrue ( one >= three,
|
|
"operator>= returned false for equal lengths");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestOperatorGreaterOrEqualReturnsFalse ()
|
|
{
|
|
const double value = 5;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Kilometer);
|
|
|
|
AssertFalse ( one >= two,
|
|
"operator>= returned true for smaller length");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestAddingTwoLengths ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 2;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Meter );
|
|
|
|
Length result = one + two;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ ( one.GetDouble (), value,
|
|
"operator+ modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ ( two.GetDouble (), value,
|
|
"operator+ modified second operand");
|
|
NS_TEST_ASSERT_MSG_EQ ( result.GetDouble (), expectedOutput,
|
|
"operator+ returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestAddingLengthAndQuantity ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 2;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
|
|
Length result = one + Length::Quantity (value, Unit::Meter);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator+ modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator+ returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestAddingQuantityAndLength ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 2;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
|
|
Length result = Length::Quantity (value, Unit::Meter) + one;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator+ modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator+ returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestSubtractingTwoLengths ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 0;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two ( value, Unit::Meter );
|
|
|
|
Length result = one - two;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator- modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), value,
|
|
"operator- modified second operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator- returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestSubtractingLengthAndQuantity ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 0;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
|
|
Length result = one - Length::Quantity ( value, Unit::Meter);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator- modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator- returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestSubtractingQuantityAndLength ()
|
|
{
|
|
const double value = 1;
|
|
const double expectedOutput = 0;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
|
|
Length result = Length::Quantity (value, Unit::Meter) - one;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator- modified second operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator- returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestMultiplyLengthByScalar ()
|
|
{
|
|
const double value = 1;
|
|
const double scalar = 5;
|
|
const double expectedOutput = value * scalar;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length result = one * scalar;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator* modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator* returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestMultiplyScalarByLength ()
|
|
{
|
|
const double value = 1;
|
|
const double scalar = 5;
|
|
const double expectedOutput = value * scalar;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length result = scalar * one;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator* modified second operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator* returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivideLengthByScalar ()
|
|
{
|
|
const double value = 10;
|
|
const double scalar = 5;
|
|
const double expectedOutput = value / scalar;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length result = one / scalar;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
|
|
"operator/ modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
|
|
"operator/ returned incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivideLengthByLength ()
|
|
{
|
|
const double valueOne = 100;
|
|
const double valueTwo = 2;
|
|
const double expectedOutput = valueOne / valueTwo;
|
|
|
|
Length one ( valueOne, Unit::Meter );
|
|
Length two ( valueTwo, Unit::Meter );
|
|
|
|
double result = one / two;
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), valueOne,
|
|
"operator/ modified first operand");
|
|
NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), valueTwo,
|
|
"operator/ modified second operand");
|
|
NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
|
|
"operator/ returned incorrect value");
|
|
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivideLengthByLengthReturnsNaN ()
|
|
{
|
|
const double value = 1;
|
|
|
|
Length one ( value, Unit::Meter );
|
|
Length two;
|
|
|
|
double result = one / two;
|
|
|
|
AssertTrue ( std::isnan (result),
|
|
"operator/ did not return NaN when dividing by zero");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivReturnsCorrectResult ()
|
|
{
|
|
const double topValue = 100;
|
|
const double bottomValue = 20;
|
|
const int64_t expectedOutput = 5;
|
|
|
|
Length numerator (topValue, Unit::Meter);
|
|
Length denominator (bottomValue, Unit::Meter);
|
|
|
|
auto result = Div (numerator, denominator);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
|
|
"Div() returned an incorrect value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivReturnsZeroRemainder ()
|
|
{
|
|
const double topValue = 100;
|
|
const double bottomValue = 20;
|
|
const int64_t expectedOutput = 5;
|
|
const int64_t expectedRemainder = 0;
|
|
|
|
Length numerator (topValue, Unit::Meter);
|
|
Length denominator (bottomValue, Unit::Meter);
|
|
Length remainder;
|
|
|
|
auto result = Div (numerator, denominator, &remainder);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
|
|
"Div() returned an incorrect value");
|
|
NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
|
|
"Div() returned an incorrect remainder");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestDivReturnsCorrectRemainder ()
|
|
{
|
|
const double topValue = 110;
|
|
const double bottomValue = 20;
|
|
const int64_t expectedOutput = 5;
|
|
const int64_t expectedRemainder = 10;
|
|
|
|
Length numerator (topValue, Unit::Meter);
|
|
Length denominator (bottomValue, Unit::Meter);
|
|
Length remainder;
|
|
|
|
auto result = Div (numerator, denominator, &remainder);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
|
|
"Div() returned an incorrect value");
|
|
NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
|
|
"Div() returned an incorrect remainder");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestModReturnsZero ()
|
|
{
|
|
Length numerator (10, Unit::Meter);
|
|
Length denominator (2, Unit::Meter);
|
|
|
|
auto result = Mod (numerator, denominator);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), 0,
|
|
"Mod() returned a non zero value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::TestModReturnsNonZero ()
|
|
{
|
|
Length numerator (14, Unit::Meter);
|
|
Length denominator (3, Unit::Meter);
|
|
const double expectedValue = 2;
|
|
|
|
auto result = Mod (numerator, denominator);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedValue,
|
|
"Mod() returned the wrong value");
|
|
}
|
|
|
|
void
|
|
LengthTestCase::DoRun ()
|
|
{
|
|
TestDefaultLengthIsZero ();
|
|
|
|
TestConstructLengthFromQuantity ();
|
|
|
|
TestConstructLengthFromSIUnits ();
|
|
|
|
TestConstructLengthFromUSUnits ();
|
|
|
|
TestLengthCopyConstructor ();
|
|
|
|
TestLengthMoveConstructor ();
|
|
|
|
TestConstructLengthFromMeterString ();
|
|
TestConstructLengthFromNanoMeterString ();
|
|
TestConstructLengthFromMicroMeterString ();
|
|
TestConstructLengthFromMilliMeterString ();
|
|
TestConstructLengthFromCentiMeterString ();
|
|
TestConstructLengthFromKiloMeterString ();
|
|
TestConstructLengthFromNauticalMileString ();
|
|
TestConstructLengthFromInchString ();
|
|
TestConstructLengthFromFootString ();
|
|
TestConstructLengthFromYardString ();
|
|
TestConstructLengthFromMileString ();
|
|
|
|
#ifdef HAVE_BOOST_UNITS
|
|
TestConstructLengthFromBoostUnits ();
|
|
#endif
|
|
|
|
TestBuilderFreeFunctions ();
|
|
|
|
TestTryParseReturnsFalse ();
|
|
TestTryParseReturnsTrue ();
|
|
|
|
TestCopyAssignment ();
|
|
TestMoveAssignment ();
|
|
TestQuantityAssignment ();
|
|
|
|
TestIsEqualReturnsTrue ();
|
|
TestIsEqualReturnsFalse ();
|
|
TestIsEqualWithToleranceReturnsTrue ();
|
|
TestIsEqualWithToleranceReturnsFalse ();
|
|
TestIsNotEqualReturnsTrue ();
|
|
TestIsNotEqualReturnsFalse ();
|
|
TestIsNotEqualWithToleranceReturnsTrue ();
|
|
TestIsNotEqualWithToleranceReturnsFalse ();
|
|
TestIsLessReturnsTrue ();
|
|
TestIsLessReturnsFalse ();
|
|
TestIsLessWithToleranceReturnsFalse ();
|
|
TestIsGreaterReturnsTrue ();
|
|
TestIsGreaterReturnsFalse ();
|
|
TestIsGreaterWithToleranceReturnsFalse ();
|
|
|
|
TestOutputStreamOperator ();
|
|
|
|
TestSerializeLengthWithUnit ();
|
|
|
|
TestOperatorEqualsReturnsTrue ();
|
|
TestOperatorEqualsReturnsFalse ();
|
|
TestOperatorNotEqualsReturnsTrue ();
|
|
TestOperatorNotEqualsReturnsFalse ();
|
|
TestOperatorLessThanReturnsTrue ();
|
|
TestOperatorLessThanReturnsFalse ();
|
|
TestOperatorLessOrEqualReturnsTrue ();
|
|
TestOperatorLessOrEqualReturnsFalse ();
|
|
TestOperatorGreaterThanReturnsTrue ();
|
|
TestOperatorGreaterThanReturnsFalse ();
|
|
TestOperatorGreaterOrEqualReturnsTrue ();
|
|
TestOperatorGreaterOrEqualReturnsFalse ();
|
|
|
|
TestAddingTwoLengths ();
|
|
TestAddingLengthAndQuantity ();
|
|
TestAddingQuantityAndLength ();
|
|
TestSubtractingTwoLengths ();
|
|
TestSubtractingLengthAndQuantity ();
|
|
TestSubtractingQuantityAndLength ();
|
|
TestMultiplyLengthByScalar ();
|
|
TestMultiplyScalarByLength ();
|
|
TestDivideLengthByScalar ();
|
|
TestDivideLengthByLength ();
|
|
TestDivideLengthByLengthReturnsNaN ();
|
|
|
|
TestDivReturnsCorrectResult ();
|
|
TestDivReturnsZeroRemainder ();
|
|
TestDivReturnsCorrectRemainder ();
|
|
|
|
TestModReturnsZero ();
|
|
TestModReturnsNonZero ();
|
|
}
|
|
|
|
/**
|
|
* \ingroup length-tests
|
|
*
|
|
* Test case for LengthValue attribute
|
|
*/
|
|
class LengthValueTestCase : public TestCase
|
|
{
|
|
public:
|
|
/**
|
|
* Default Constructor
|
|
*/
|
|
LengthValueTestCase ()
|
|
: TestCase ("length-value-tests")
|
|
{}
|
|
|
|
/**
|
|
* Destructor
|
|
*/
|
|
virtual ~LengthValueTestCase ()
|
|
{}
|
|
|
|
private:
|
|
//class with Length attribute
|
|
class TestObject : public Object
|
|
{
|
|
public:
|
|
static TypeId GetTypeId ();
|
|
|
|
TestObject ()
|
|
: m_length ()
|
|
{}
|
|
|
|
virtual ~TestObject ()
|
|
{}
|
|
|
|
private:
|
|
Length m_length;
|
|
};
|
|
|
|
private:
|
|
/**
|
|
* Test that a LengthValue can be constructed from a Length instance
|
|
*/
|
|
void TestAttributeConstructor ();
|
|
|
|
/**
|
|
* Test that a LengthValue can be serialized to a string
|
|
*/
|
|
void TestAttributeSerialization ();
|
|
|
|
/**
|
|
* Test that a LengthValue can be deserialized from a string
|
|
*/
|
|
void TestAttributeDeserialization ();
|
|
|
|
/**
|
|
* Test that a LengthValue works as an attribute
|
|
*/
|
|
void TestObjectAttribute ();
|
|
|
|
/**
|
|
* Test that a StringValue is converted to LengthValue
|
|
*/
|
|
void TestSetAttributeUsingStringValue ();
|
|
|
|
// Inherited function
|
|
virtual void DoRun ();
|
|
};
|
|
|
|
TypeId
|
|
LengthValueTestCase::TestObject::GetTypeId ()
|
|
{
|
|
static TypeId tid = TypeId ("LengthValueTestCase::TestObject")
|
|
.SetParent<Object> ()
|
|
.SetGroupName ("Test")
|
|
.AddConstructor<TestObject> ()
|
|
.AddAttribute ("Length",
|
|
"Length value",
|
|
LengthValue (),
|
|
MakeLengthAccessor (&TestObject::m_length),
|
|
MakeLengthChecker ())
|
|
;
|
|
|
|
return tid;
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::TestAttributeConstructor ()
|
|
{
|
|
Length l = KiloMeters (2);
|
|
LengthValue value (l);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (value.Get (), l, "Length attribute has wrong value");
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::TestAttributeSerialization ()
|
|
{
|
|
Ptr<const AttributeChecker> checker = MakeLengthChecker ();
|
|
|
|
Length l = KiloMeters (2);
|
|
LengthValue value (l);
|
|
|
|
std::string output = value.SerializeToString (checker);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (output, "2000 m",
|
|
"Length attribute serialization has wrong output");
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::TestAttributeDeserialization ()
|
|
{
|
|
Ptr<const AttributeChecker> checker = MakeLengthChecker ();
|
|
|
|
Length l = KiloMeters (2);
|
|
std::ostringstream stream;
|
|
stream << l;
|
|
|
|
LengthValue value;
|
|
bool result = value.DeserializeFromString (stream.str (), checker);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (result, true,
|
|
"Length attribute deserialization failed");
|
|
NS_TEST_ASSERT_MSG_EQ (value.Get (), l,
|
|
"Length attribute has wrong value after deserialization");
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::TestObjectAttribute ()
|
|
{
|
|
Length expected (5, Unit::Kilometer);
|
|
Ptr<TestObject> obj = CreateObject<TestObject> ();
|
|
|
|
obj->SetAttribute ("Length", LengthValue (expected));
|
|
|
|
LengthValue val;
|
|
obj->GetAttribute ("Length", val);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
|
|
"Length attribute does not have expected value");
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::TestSetAttributeUsingStringValue ()
|
|
{
|
|
Length expected (5, Unit::Kilometer);
|
|
Ptr<TestObject> obj = CreateObject<TestObject> ();
|
|
|
|
std::stringstream stream;
|
|
stream << expected.As (Unit::Kilometer);
|
|
|
|
obj->SetAttribute ("Length", StringValue (stream.str()));
|
|
|
|
LengthValue val;
|
|
obj->GetAttribute ("Length", val);
|
|
|
|
NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
|
|
"Length attribute does not have expected value");
|
|
}
|
|
|
|
void
|
|
LengthValueTestCase::DoRun ()
|
|
{
|
|
TestAttributeConstructor ();
|
|
TestAttributeSerialization ();
|
|
TestAttributeDeserialization ();
|
|
TestObjectAttribute ();
|
|
TestSetAttributeUsingStringValue ();
|
|
}
|
|
|
|
/**
|
|
* \ingroup length-tests
|
|
* The Test Suite that runs the test case
|
|
*/
|
|
class LengthTestSuite : public TestSuite
|
|
{
|
|
public:
|
|
/**
|
|
* Default Constructor
|
|
*/
|
|
LengthTestSuite ();
|
|
};
|
|
|
|
LengthTestSuite::LengthTestSuite ()
|
|
: TestSuite ("length")
|
|
{
|
|
AddTestCase ( new LengthTestCase (), TestCase::QUICK );
|
|
AddTestCase ( new LengthValueTestCase (), TestCase::QUICK );
|
|
}
|
|
|
|
/**
|
|
* LengthTestSuite instance
|
|
*/
|
|
static LengthTestSuite gLengthTestSuite;
|
|
|