20#include "ns3/length.h"
22#include "ns3/object.h"
23#include "ns3/string.h"
27#include <boost/units/base_units/us/foot.hpp>
28#include <boost/units/systems/si.hpp>
29#include <boost/units/systems/si/prefixes.hpp>
35#include <initializer_list>
147 const std::initializer_list<std::string>& symbols);
166#ifdef HAVE_BOOST_UNITS
171 void TestConstructLengthFromBoostUnits();
172 void TestConstructLengthFromBoostUnitsMeters();
173 void TestConstructLengthFromBoostUnitsKiloMeters();
174 void TestConstructLengthFromBoostUnitsFeet();
257 const std::string& expectedOutput,
258 const std::string& context);
317 void DoRun()
override;
337 "length constructed from meters has wrong value");
343 using TestEntry = std::tuple<Length, std::string>;
345 const double expectedMeters = 1;
346 const std::initializer_list<TestEntry> inputs{
347 std::make_tuple(
Length(1e9, Unit::Nanometer),
"nanometer"),
348 std::make_tuple(
Length(1e6, Unit::Micrometer),
"micrometer"),
349 std::make_tuple(
Length(1e3, Unit::Millimeter),
"millimeter"),
350 std::make_tuple(
Length(1e2, Unit::Centimeter),
"centimeter"),
351 std::make_tuple(
Length(1e-3, Unit::Kilometer),
"kilometer"),
352 std::make_tuple(
Length((1 / 1852.0), Unit::NauticalMile),
"nautical_mile")};
354 for (
const TestEntry& entry : inputs)
356 const Length& l = std::get<0>(entry);
357 const std::string& context = std::get<1>(entry);
361 context <<
": constructed length from SI unit has wrong value");
368 using TestEntry = std::tuple<Length, std::string>;
370 const double expectedMeters = 0.3048;
371 const double tolerance = 0.0001;
373 const std::initializer_list<TestEntry> inputs{
374 std::make_tuple(
Length(12.0, Unit::Inch),
"inch"),
375 std::make_tuple(
Length(1.0, Unit::Foot),
"foot"),
376 std::make_tuple(
Length((1 / 3.0), Unit::Yard),
"yard"),
377 std::make_tuple(
Length((1 / 5280.0), Unit::Mile),
"mile"),
380 for (
const TestEntry& entry : inputs)
382 const Length& l = std::get<0>(entry);
383 const std::string& context = std::get<1>(entry);
388 "constructed length from US unit (" << context
389 <<
") has wrong value");
396 const double value = 5;
403 "copy constructed length has wrong value");
409 const double value = 5;
412 Length copy(std::move(original));
421 const std::initializer_list<std::string>& symbols)
423 const std::array<std::string, 2> SEPARATORS{{
"",
" "}};
425 for (
const std::string& symbol : symbols)
427 for (
const std::string& separator : SEPARATORS)
429 std::ostringstream stream;
431 stream << unitValue << separator << symbol;
435 std::ostringstream msg;
436 msg <<
"string constructed length has wrong value: '" << stream.str() <<
"'";
446 const double value = 5;
454 const double value = 5;
455 const double expectedValue = 5e-9;
460 {
"nm",
"nanometer",
"nanometers",
"nanometre",
"nanometres"});
466 const double value = 5;
467 const double expectedValue = 5e-6;
468 const double tolerance = 1e-7;
473 {
"um",
"micrometer",
"micrometers",
"micrometre",
"micrometres"});
479 const double value = 5;
480 const double expectedValue = 5e-3;
481 const double tolerance = 1e-4;
486 {
"mm",
"millimeter",
"millimeters",
"millimetre",
"millimetres"});
492 const double value = 5;
493 const double expectedValue = 5e-2;
494 const double tolerance = 1e-3;
499 {
"cm",
"centimeter",
"centimeters",
"centimetre",
"centimetres"});
505 const double value = 5;
506 const double expectedValue = 5e3;
511 {
"km",
"kilometer",
"kilometers",
"kilometre",
"kilometres"});
517 const double value = 5;
518 const double expectedValue = 9260;
523 {
"nmi",
"nautical mile",
"nautical miles"});
529 const double value = 5;
530 const double expectedValue = 0.127;
531 const double tolerance = 1e-4;
539 const double value = 5;
540 const double expectedValue = 1.524;
541 const double tolerance = 1e-4;
549 const double value = 5;
550 const double expectedValue = 4.572;
551 const double tolerance = 1e-4;
559 const double value = 5;
560 const double expectedValue = 8046.72;
561 const double tolerance = 1e-3;
566#ifdef HAVE_BOOST_UNITS
568LengthTestCase::TestConstructLengthFromBoostUnits()
570 TestConstructLengthFromBoostUnitsMeters();
571 TestConstructLengthFromBoostUnitsKiloMeters();
572 TestConstructLengthFromBoostUnitsFeet();
576LengthTestCase::TestConstructLengthFromBoostUnitsMeters()
578 namespace bu = boost::units;
580 auto meters = 5 * bu::si::meter;
586 "Construction from boost::units meters produced "
591LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters()
593 namespace bu = boost::units;
594 auto kilometer = bu::si::kilo * bu::si::meter;
596 const double expectedValue = 5000;
597 auto quantity = 5 * kilometer;
603 "Construction from boost::units kilometers produced "
608LengthTestCase::TestConstructLengthFromBoostUnitsFeet()
610 namespace bu = boost::units;
612 bu::us::foot_base_unit::unit_type Foot;
614 const double expectedValue = 3.048;
615 auto feet = 10 * Foot;
622 "Construction from boost::units foot produced "
630 using Builder = std::function<
Length(
double)>;
632 double inputValue = 10;
634 std::map<Unit, Builder> TESTDATA{{Unit::Nanometer,
NanoMeters},
644 {Unit::Mile,
Miles}};
646 for (
auto& entry : TESTDATA)
648 Length expected(inputValue, entry.first);
650 Length output = entry.second(inputValue);
654 "The builder free function for "
656 <<
" did not create a Length with the correct value");
663 auto l = Length::TryParse(1,
"");
665 AssertFalse(l.has_value(),
"TryParse returned true on bad input");
671 using TestInput = std::pair<double, std::string>;
672 using TestArgs = std::pair<double, double>;
673 std::map<TestInput, TestArgs> tests{{{5,
"m"}, {5, 0}},
675 {{5,
"kilometer"}, {5e3, 0}},
676 {{5,
" kilometer"}, {5e3, 0}}};
678 for (
auto& entry : tests)
680 TestInput input = entry.first;
681 TestArgs
args = entry.second;
683 auto l = Length::TryParse(input.first, input.second);
685 AssertTrue(l.has_value(),
"TryParse returned false when expecting true");
687 std::stringstream stream;
688 stream <<
"Parsing input (" << input.first <<
", " << input.second
689 <<
") returned the wrong value";
698 const double value = 5;
711 const double value = 5;
716 copy = std::move(original);
737 const double value = 5;
747 const double value = 5;
757 const double value = 5;
758 const double tolerance = 0.1;
763 AssertTrue(one.
IsEqual(two, tolerance),
"IsEqual returned false for almost equal lengths");
769 const double value = 5;
770 const double tolerance = 0.01;
775 AssertFalse(one.
IsEqual(two, tolerance),
"IsEqual returned true for almost equal lengths");
781 const double value = 5;
792 const double value = 5;
803 const double tolerance = 0.001;
805 Length one(5.01, Unit::Meter);
806 Length two(5.02, Unit::Meter);
809 "IsNotEqual with tolerance returned false for not equal lengths");
815 const double tolerance = 0.01;
817 Length one(5.01, Unit::Meter);
818 Length two(5.02, Unit::Meter);
821 "IsNotEqual with tolerance returned true for not equal lengths");
827 const double value = 5;
838 const double value = 5;
849 const double tolerance = 0.01;
851 Length one(5.1234, Unit::Meter);
852 Length two(5.1278, Unit::Meter);
860 Length one(2.0, Unit::Meter);
861 Length two(1.0, Unit::Meter);
869 Length one(2.0, Unit::Meter);
870 Length two(1.0, Unit::Meter);
878 const double tolerance = 0.01;
880 Length one(5.1234, Unit::Meter);
881 Length two(5.1278, Unit::Meter);
889 Length l(1.0, Unit::Meter);
891 std::stringstream stream;
901 const double value = 5;
905 std::stringstream stream;
907 stream <<
value <<
"m";
918 const std::string& expectedOutput,
919 const std::string& context)
921 const std::string msg = context +
": unexpected output when serializing length";
923 std::ostringstream stream;
925 stream << std::fixed << std::setprecision(5) << l.
As(unit);
933 Length l(1.0, Unit::Meter);
951 const double value = 5;
956 AssertTrue(one == two,
"operator== returned false for equal lengths");
962 const double value = 5;
967 AssertFalse(one == two,
"operator== returned true for non equal lengths");
973 const double value = 5;
978 AssertTrue(one != two,
"operator!= returned false for non equal lengths");
984 const double value = 5;
989 AssertFalse(one != two,
"operator!= returned true for equal lengths");
995 const double value = 5;
1000 AssertTrue(one < two,
"operator< returned false for smaller length");
1006 const double value = 5;
1011 AssertFalse(two < one,
"operator< returned true for larger length");
1017 const double value = 5;
1023 AssertTrue(one <= two,
"operator<= returned false for smaller length");
1025 AssertTrue(one <= three,
"operator<= returned false for equal lengths");
1031 const double value = 5;
1036 AssertFalse(two <= one,
"operator<= returned true for larger length");
1042 const double value = 5;
1047 AssertTrue(two > one,
"operator> returned false for larger length");
1053 const double value = 5;
1058 AssertFalse(one > two,
"operator> returned true for smaller length");
1064 const double value = 5;
1070 AssertTrue(two >= one,
"operator>= returned false for larger length");
1072 AssertTrue(one >= three,
"operator>= returned false for equal lengths");
1078 const double value = 5;
1083 AssertFalse(one >= two,
"operator>= returned true for smaller length");
1089 const double value = 1;
1090 const double expectedOutput = 2;
1095 Length result = one + two;
1105 const double value = 1;
1106 const double expectedOutput = 2;
1119 const double value = 1;
1120 const double expectedOutput = 2;
1133 const double value = 1;
1134 const double expectedOutput = 0;
1139 Length result = one - two;
1149 const double value = 1;
1150 const double expectedOutput = 0;
1163 const double value = 1;
1164 const double expectedOutput = 0;
1177 const double value = 1;
1178 const double scalar = 5;
1179 const double expectedOutput =
value * scalar;
1182 Length result = one * scalar;
1191 const double value = 1;
1192 const double scalar = 5;
1193 const double expectedOutput =
value * scalar;
1196 Length result = scalar * one;
1205 const double value = 10;
1206 const double scalar = 5;
1207 const double expectedOutput =
value / scalar;
1210 Length result = one / scalar;
1219 const double valueOne = 100;
1220 const double valueTwo = 2;
1221 const double expectedOutput = valueOne / valueTwo;
1223 Length one(valueOne, Unit::Meter);
1224 Length two(valueTwo, Unit::Meter);
1226 double result = one / two;
1236 const double value = 1;
1241 double result = one / two;
1243 AssertTrue(std::isnan(result),
"operator/ did not return NaN when dividing by zero");
1249 const double topValue = 100;
1250 const double bottomValue = 20;
1251 const int64_t expectedOutput = 5;
1253 Length numerator(topValue, Unit::Meter);
1254 Length denominator(bottomValue, Unit::Meter);
1256 auto result =
Div(numerator, denominator);
1264 const double topValue = 100;
1265 const double bottomValue = 20;
1266 const int64_t expectedOutput = 5;
1267 const int64_t expectedRemainder = 0;
1269 Length numerator(topValue, Unit::Meter);
1270 Length denominator(bottomValue, Unit::Meter);
1273 auto result =
Div(numerator, denominator, &remainder);
1278 "Div() returned an incorrect remainder");
1284 const double topValue = 110;
1285 const double bottomValue = 20;
1286 const int64_t expectedOutput = 5;
1287 const int64_t expectedRemainder = 10;
1289 Length numerator(topValue, Unit::Meter);
1290 Length denominator(bottomValue, Unit::Meter);
1293 auto result =
Div(numerator, denominator, &remainder);
1298 "Div() returned an incorrect remainder");
1304 Length numerator(10, Unit::Meter);
1305 Length denominator(2, Unit::Meter);
1307 auto result =
Mod(numerator, denominator);
1315 Length numerator(14, Unit::Meter);
1316 Length denominator(3, Unit::Meter);
1317 const double expectedValue = 2;
1319 auto result =
Mod(numerator, denominator);
1351#ifdef HAVE_BOOST_UNITS
1352 TestConstructLengthFromBoostUnits();
1490 void DoRun()
override;
1496 static TypeId tid =
TypeId(
"LengthValueTestCase::TestObject")
1498 .SetGroupName(
"Test")
1500 .AddAttribute(
"Length",
1526 std::string output =
value.SerializeToString(checker);
1537 std::ostringstream stream;
1541 bool result =
value.DeserializeFromString(stream.str(), checker);
1550 Length expected(5, Unit::Kilometer);
1553 obj->SetAttribute(
"Length",
LengthValue(expected));
1556 obj->GetAttribute(
"Length", val);
1564 Length expected(5, Unit::Kilometer);
1567 std::stringstream stream;
1568 stream << expected.
As(Unit::Kilometer);
1570 obj->SetAttribute(
"Length",
StringValue(stream.str()));
1573 obj->GetAttribute(
"Length", val);
Implements tests for the Length class.
void TestAddingLengthAndQuantity()
Test arithmetic operations.
void TestIsGreaterReturnsFalse()
Test member comparison operators.
void TestOperatorGreaterOrEqualReturnsTrue()
Test free function comparison operators.
void TestOperatorEqualsReturnsFalse()
Test free function comparison operators.
void TestTryParseReturnsTrue()
Test the TryParse function returns true on success.
void TestConstructLengthFromMeterString()
Test that a length object can be constructed from a string.
void TestDivReturnsZeroRemainder()
Test Div function.
void TestBuilderFreeFunctions()
Test constructing length objects using the builder free functions.
void TestConstructLengthFromMileString()
Test that a length object can be constructed from a string.
void TestIsEqualWithToleranceReturnsFalse()
Test member comparison operators.
void TestDivReturnsCorrectRemainder()
Test Div function.
void TestModReturnsZero()
Test Mod function.
void TestConstructLengthFromCentiMeterString()
Test that a length object can be constructed from a string.
void TestDivideLengthByScalar()
Test arithmetic operations.
void TestModReturnsNonZero()
Test Mod function.
void TestLengthMoveConstructor()
Test that the value from one length is copied to another using the move constructor.
void TestTryParseReturnsFalse()
Test the TryParse function returns false on bad input.
void TestCopyAssignment()
Test that a length object can be updated by assignment from another length object.
void TestIsNotEqualReturnsTrue()
Test member comparison operators.
void TestConstructLengthFromFootString()
Test that a length object can be constructed from a string.
void TestInputStreamOperator()
Test reading length object from a stream produces the expected length value.
void TestDivideLengthByLengthReturnsNaN()
Test arithmetic operations.
void TestIsNotEqualWithToleranceReturnsFalse()
Test member comparison operators.
void TestOperatorLessOrEqualReturnsTrue()
Test free function comparison operators.
void TestIsLessReturnsFalse()
Test member comparison operators.
void TestSubtractingQuantityAndLength()
Test arithmetic operations.
void TestConstructLengthFromMilliMeterString()
Test that a length object can be constructed from a string.
void TestConstructLengthFromInchString()
Test that a length object can be constructed from a string.
void TestConstructLengthFromSIUnits()
Test that a Length object constructed from various SI units has the correct value in meters.
void DoRun() override
Implementation to actually run this TestCase.
void TestConstructLengthFromNanoMeterString()
Test that a length object can be constructed from a string.
void TestMultiplyLengthByScalar()
Test arithmetic operations.
void AssertTrue(bool condition, std::string msg)
Helper function to compare results with true.
void TestIsEqualReturnsFalse()
Test member comparison operators.
void TestConstructLengthFromQuantity()
Test that a Length object can be constructed from a Quantity object.
void TestConstructLengthFromKiloMeterString()
Test that a length object can be constructed from a string.
void TestDefaultLengthIsZero()
Test that a default constructed Length object has a value of 0.
void TestOperatorEqualsReturnsTrue()
Test free function comparison operators.
void TestConstructLengthFromUSUnits()
Test that a Length object constructed from various US units has the correct value in meters.
void AssertFalse(bool condition, std::string msg)
Helper function to compare results with false.
void TestIsEqualReturnsTrue()
Test member comparison operators.
void TestIsNotEqualWithToleranceReturnsTrue()
Test member comparison operators.
void TestOperatorLessThanReturnsFalse()
Test free function comparison operators.
void TestIsGreaterWithToleranceReturnsFalse()
Test member comparison operators.
void TestLengthSerialization(const Length &l, const T &unit, const std::string &expectedOutput, const std::string &context)
Generic function for testing serialization of a Length object in various units.
void TestSubtractingLengthAndQuantity()
Test arithmetic operations.
void TestSubtractingTwoLengths()
Test arithmetic operations.
void TestDivideLengthByLength()
Test arithmetic operations.
void TestDivReturnsCorrectResult()
Test Div function.
void TestAddingQuantityAndLength()
Test arithmetic operations.
void TestIsNotEqualReturnsFalse()
Test member comparison operators.
void TestConstructLengthFromMicroMeterString()
Test that a length object can be constructed from a string.
void TestOperatorGreaterThanReturnsTrue()
Test free function comparison operators.
void TestOutputStreamOperator()
Test writing length object to a stream produces the expected output.
LengthTestCase()
Constructor.
void TestConstructLengthFromYardString()
Test that a length object can be constructed from a string.
void TestAddingTwoLengths()
Test arithmetic operations.
void TestConstructLengthFromNauticalMileString()
Test that a length object can be constructed from a string.
void TestIsLessReturnsTrue()
Test member comparison operators.
void TestOperatorGreaterThanReturnsFalse()
Test free function comparison operators.
void TestOperatorLessThanReturnsTrue()
Test free function comparison operators.
void TestOperatorNotEqualsReturnsFalse()
Test free function comparison operators.
void TestMoveAssignment()
Test that a length object can be updated by assignment from a moved length object.
void TestOperatorLessOrEqualReturnsFalse()
Test free function comparison operators.
void TestConstructLengthFromString(double unitValue, double meterValue, double tolerance, const std::initializer_list< std::string > &symbols)
Test that a length object can be constructed from a string.
void TestSerializeLengthWithUnit()
Test serializing a length object to all of the supported unit types.
void TestOperatorGreaterOrEqualReturnsFalse()
Test free function comparison operators.
void TestLengthCopyConstructor()
Test that the value from one length is copied to another using the copy constructor.
~LengthTestCase() override=default
Destructor.
void TestOperatorNotEqualsReturnsTrue()
Test free function comparison operators.
void TestMultiplyScalarByLength()
Test arithmetic operations.
void TestIsLessWithToleranceReturnsFalse()
Test member comparison operators.
void TestIsGreaterReturnsTrue()
Test member comparison operators.
void TestQuantityAssignment()
Test that a length object can be updated by assignment from a quantity.
void TestIsEqualWithToleranceReturnsTrue()
Test member comparison operators.
The Test Suite that runs the test case.
LengthTestSuite()
Default Constructor.
Class with Length attribute.
static TypeId GetTypeId()
Get the type ID.
Length m_length
Length object.
Test case for LengthValue attribute.
void TestAttributeSerialization()
Test that a LengthValue can be serialized to a string.
void TestObjectAttribute()
Test that a LengthValue works as an attribute.
LengthValueTestCase()
Default Constructor.
void TestAttributeConstructor()
Test that a LengthValue can be constructed from a Length instance.
void TestAttributeDeserialization()
Test that a LengthValue can be deserialized from a string.
void DoRun() override
Implementation to actually run this TestCase.
void TestSetAttributeUsingStringValue()
Test that a StringValue is converted to LengthValue.
~LengthValueTestCase() override
Destructor.
An immutable class which represents a value in a specific length unit.
double Value() const
The value of the quantity.
Represents a length in meters.
double GetDouble() const
Current length value.
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Unit
Units of length in various measurement systems that are supported by the Length class.
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
AttributeValue implementation for Length.
A base class which provides memory management and object aggregation.
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
a unique identifier for an interface.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Ptr< const AttributeChecker > MakeLengthChecker()
Ptr< const AttributeAccessor > MakeLengthAccessor(T1 a1)
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Length Yards(double value)
Construct a length from a value in the indicated unit.
Length Feet(double value)
Construct a length from a value in the indicated unit.
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Length Miles(double value)
Construct a length from a value in the indicated unit.
Length Meters(double value)
Construct a length from a value in the indicated unit.
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Length Inches(double value)
Construct a length from a value in the indicated unit.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_ASSERT_MSG_EQ_TOL(actual, limit, tol, msg)
Test that actual and expected (limit) values are equal to plus or minus some tolerance and report and...
Length::Unit Unit
Save some typing by defining a short alias for Length::Unit.
static LengthTestSuite gLengthTestSuite
LengthTestSuite instance.
Every class exported by the ns3 library is enclosed in the ns3 namespace.