A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
length-test-suite.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2019 Lawrence Livermore National Laboratory
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Authors: Mathew Bielejeski<bielejeski1@llnl.gov>
18 */
19
20#include "ns3/length.h"
21#include "ns3/log.h"
22#include "ns3/object.h"
23#include "ns3/string.h"
24#include "ns3/test.h"
25
26#ifdef HAVE_BOOST
27#include <boost/units/base_units/us/foot.hpp>
28#include <boost/units/systems/si.hpp>
29#include <boost/units/systems/si/prefixes.hpp>
30#endif
31
32#include <array>
33#include <cmath>
34#include <functional>
35#include <initializer_list>
36#include <iomanip>
37#include <limits>
38#include <map>
39#include <sstream>
40#include <string>
41
42/**
43 * \file
44 * \ingroup length-tests
45 * Length class tests.
46 */
47
48/**
49 * \ingroup core-tests length
50 * \defgroup length-tests Length test suite
51 */
52
53using namespace ns3;
54
55/**
56 * Save some typing by defining a short alias for Length::Unit
57 */
59
60/**
61 * Implements tests for the Length class
62 */
64{
65 public:
66 /**
67 * Constructor
68 */
70 : TestCase("length-tests")
71 {
72 }
73
74 /**
75 * Destructor
76 */
77 ~LengthTestCase() override = default;
78
79 protected:
80 /**
81 * Helper function to compare results with false
82 *
83 * \param condition The boolean condition to test
84 * \param msg The message to print if the test fails
85 */
86 void AssertFalse(bool condition, std::string msg)
87 {
88 NS_TEST_ASSERT_MSG_EQ(condition, false, msg);
89 }
90
91 /**
92 * Helper function to compare results with true
93 *
94 * \param condition The boolean condition to test
95 * \param msg The message to print if the test fails
96 */
97 void AssertTrue(bool condition, std::string msg)
98 {
99 NS_TEST_ASSERT_MSG_EQ(condition, true, msg);
100 }
101
102 private:
103 /**
104 * Test that a default constructed Length object has a value of 0
105 */
107
108 /**
109 * Test that a Length object can be constructed from a Quantity object
110 */
112
113 /**
114 * Test that a Length object constructed from various SI units has the
115 * correct value in meters
116 */
118
119 /**
120 * Test that a Length object constructed from various US units has the
121 * correct value in meters
122 */
124
125 /**
126 * Test that the value from one length is copied to another
127 * using the copy constructor.
128 */
130
131 /**
132 * Test that the value from one length is copied to another
133 * using the move constructor.
134 */
136
137 /**
138 * Test that a length object can be constructed from a string
139 * \param unitValue //!< Value to test.
140 * \param meterValue //!< Reference value [m].
141 * \param tolerance //!< Tolerance.
142 * \param symbols //!< Unit symbols.
143 */
144 void TestConstructLengthFromString(double unitValue,
145 double meterValue,
146 double tolerance,
147 const std::initializer_list<std::string>& symbols);
148
149 /**
150 * Test that a length object can be constructed from a string
151 * @{
152 */
164 /** @} */
165
166#ifdef HAVE_BOOST_UNITS
167 /**
168 * Test construction from boost::units
169 * @{
170 */
171 void TestConstructLengthFromBoostUnits();
172 void TestConstructLengthFromBoostUnitsMeters();
173 void TestConstructLengthFromBoostUnitsKiloMeters();
174 void TestConstructLengthFromBoostUnitsFeet();
175 /** @} */
176#endif
177
178 /**
179 * Test constructing length objects using the builder free functions
180 * @{
181 */
183 /** @} */
184
185 /**
186 * Test the TryParse function returns false on bad input
187 */
189
190 /**
191 * Test the TryParse function returns true on success
192 */
194
195 /**
196 * Test that a length object can be updated by assignment from another
197 * length object
198 */
199 void TestCopyAssignment();
200
201 /**
202 * Test that a length object can be updated by assignment from a moved
203 * length object
204 */
205 void TestMoveAssignment();
206
207 /**
208 * Test that a length object can be updated by assignment from a quantity
209 */
211
212 /**
213 * Test member comparison operators
214 * @{
215 */
230 /** @} */
231
232 /**
233 * Test writing length object to a stream produces the expected output
234 */
236
237 /**
238 * Test reading length object from a stream produces the expected length
239 * value
240 */
242
243 /**
244 * Generic function for testing serialization of a Length object in
245 * various units
246 *
247 * \tparam T Type of the length unit that should be output during serialization
248 *
249 * \param l Length object to serialize
250 * \param unit Unit that the length value will be converted to before serialization
251 * \param expectedOutput Expected result of the serialization
252 * \param context Included in the error message if the test fails
253 */
254 template <class T>
255 void TestLengthSerialization(const Length& l,
256 const T& unit,
257 const std::string& expectedOutput,
258 const std::string& context);
259
260 /**
261 * Test serializing a length object to all of the supported unit types
262 */
264
265 /**
266 * Test free function comparison operators
267 * @{
268 */
281 /** @} */
282
283 /**
284 * Test arithmetic operations
285 * @{
286 */
298 /** @} */
299
300 /**
301 * Test Div function
302 * @{
303 */
307 /** @} */
308
309 /**
310 * Test Mod function
311 * @{
312 */
313 void TestModReturnsZero();
315 /** @} */
316
317 void DoRun() override;
318};
319
320void
322{
323 Length l;
324
325 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(), 0, "Default value of Length is not 0");
326}
327
328void
330{
331 const Length::Quantity VALUE(5.0, Unit::Meter);
332
333 Length l(VALUE);
334
336 VALUE.Value(),
337 "length constructed from meters has wrong value");
338}
339
340void
342{
343 using TestEntry = std::tuple<Length, std::string>;
344
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")};
353
354 for (const TestEntry& entry : inputs)
355 {
356 const Length& l = std::get<0>(entry);
357 const std::string& context = std::get<1>(entry);
358
360 expectedMeters,
361 context << ": constructed length from SI unit has wrong value");
362 }
363}
364
365void
367{
368 using TestEntry = std::tuple<Length, std::string>;
369
370 const double expectedMeters = 0.3048;
371 const double tolerance = 0.0001;
372
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"),
378 };
379
380 for (const TestEntry& entry : inputs)
381 {
382 const Length& l = std::get<0>(entry);
383 const std::string& context = std::get<1>(entry);
384
386 expectedMeters,
387 tolerance,
388 "constructed length from US unit (" << context
389 << ") has wrong value");
390 }
391}
392
393void
395{
396 const double value = 5;
397 Length original(value, Unit::Meter);
398
399 Length copy(original);
400
402 original.GetDouble(),
403 "copy constructed length has wrong value");
404}
405
406void
408{
409 const double value = 5;
410 Length original(value, Unit::Meter);
411
412 Length copy(std::move(original));
413
414 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), value, "move constructed length has wrong value");
415}
416
417void
419 double meterValue,
420 double tolerance,
421 const std::initializer_list<std::string>& symbols)
422{
423 const std::array<std::string, 2> SEPARATORS{{"", " "}};
424
425 for (const std::string& symbol : symbols)
426 {
427 for (const std::string& separator : SEPARATORS)
428 {
429 std::ostringstream stream;
430
431 stream << unitValue << separator << symbol;
432
433 Length l(stream.str());
434
435 std::ostringstream msg;
436 msg << "string constructed length has wrong value: '" << stream.str() << "'";
437
438 NS_TEST_ASSERT_MSG_EQ_TOL(l.GetDouble(), meterValue, tolerance, msg.str());
439 }
440 }
441}
442
443void
445{
446 const double value = 5;
447
448 TestConstructLengthFromString(value, value, 0, {"m", "meter", "meters", "metre", "metres"});
449}
450
451void
453{
454 const double value = 5;
455 const double expectedValue = 5e-9;
456
458 expectedValue,
459 0,
460 {"nm", "nanometer", "nanometers", "nanometre", "nanometres"});
461}
462
463void
465{
466 const double value = 5;
467 const double expectedValue = 5e-6;
468 const double tolerance = 1e-7;
469
471 expectedValue,
472 tolerance,
473 {"um", "micrometer", "micrometers", "micrometre", "micrometres"});
474}
475
476void
478{
479 const double value = 5;
480 const double expectedValue = 5e-3;
481 const double tolerance = 1e-4;
482
484 expectedValue,
485 tolerance,
486 {"mm", "millimeter", "millimeters", "millimetre", "millimetres"});
487}
488
489void
491{
492 const double value = 5;
493 const double expectedValue = 5e-2;
494 const double tolerance = 1e-3;
495
497 expectedValue,
498 tolerance,
499 {"cm", "centimeter", "centimeters", "centimetre", "centimetres"});
500}
501
502void
504{
505 const double value = 5;
506 const double expectedValue = 5e3;
507
509 expectedValue,
510 0,
511 {"km", "kilometer", "kilometers", "kilometre", "kilometres"});
512}
513
514void
516{
517 const double value = 5;
518 const double expectedValue = 9260;
519
521 expectedValue,
522 0,
523 {"nmi", "nautical mile", "nautical miles"});
524}
525
526void
528{
529 const double value = 5;
530 const double expectedValue = 0.127;
531 const double tolerance = 1e-4;
532
533 TestConstructLengthFromString(value, expectedValue, tolerance, {"in", "inch", "inches"});
534}
535
536void
538{
539 const double value = 5;
540 const double expectedValue = 1.524;
541 const double tolerance = 1e-4;
542
543 TestConstructLengthFromString(value, expectedValue, tolerance, {"ft", "foot", "feet"});
544}
545
546void
548{
549 const double value = 5;
550 const double expectedValue = 4.572;
551 const double tolerance = 1e-4;
552
553 TestConstructLengthFromString(value, expectedValue, tolerance, {"yd", "yard", "yards"});
554}
555
556void
558{
559 const double value = 5;
560 const double expectedValue = 8046.72;
561 const double tolerance = 1e-3;
562
563 TestConstructLengthFromString(value, expectedValue, tolerance, {"mi", "mile", "miles"});
564}
565
566#ifdef HAVE_BOOST_UNITS
567void
568LengthTestCase::TestConstructLengthFromBoostUnits()
569{
570 TestConstructLengthFromBoostUnitsMeters();
571 TestConstructLengthFromBoostUnitsKiloMeters();
572 TestConstructLengthFromBoostUnitsFeet();
573}
574
575void
576LengthTestCase::TestConstructLengthFromBoostUnitsMeters()
577{
578 namespace bu = boost::units;
579
580 auto meters = 5 * bu::si::meter;
581
582 Length l(meters);
583
584 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(),
585 meters.value(),
586 "Construction from boost::units meters produced "
587 "incorrect value");
588}
589
590void
591LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters()
592{
593 namespace bu = boost::units;
594 auto kilometer = bu::si::kilo * bu::si::meter;
595
596 const double expectedValue = 5000;
597 auto quantity = 5 * kilometer;
598
599 Length l(quantity);
600
601 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(),
602 expectedValue,
603 "Construction from boost::units kilometers produced "
604 "incorrect value");
605}
606
607void
608LengthTestCase::TestConstructLengthFromBoostUnitsFeet()
609{
610 namespace bu = boost::units;
611
612 bu::us::foot_base_unit::unit_type Foot;
613
614 const double expectedValue = 3.048;
615 auto feet = 10 * Foot;
616
617 Length l(feet);
618
619 NS_TEST_ASSERT_MSG_EQ_TOL(l.GetDouble(),
620 expectedValue,
621 0.001,
622 "Construction from boost::units foot produced "
623 "incorrect value");
624}
625#endif
626
627void
629{
630 using Builder = std::function<Length(double)>;
631
632 double inputValue = 10;
633
634 std::map<Unit, Builder> TESTDATA{
635 {Unit::Nanometer, NanoMeters},
636 {Unit::Micrometer, MicroMeters},
637 {Unit::Millimeter, MilliMeters},
638 {Unit::Centimeter, CentiMeters},
639 {Unit::Meter, Meters},
640 {Unit::Kilometer, KiloMeters},
641 {Unit::NauticalMile, NauticalMiles},
642 {Unit::Inch, Inches},
643 {Unit::Foot, Feet},
644 {Unit::Yard, Yards},
645 {Unit::Mile, Miles},
646 };
647
648 for (auto& entry : TESTDATA)
649 {
650 Length expected(inputValue, entry.first);
651
652 Length output = entry.second(inputValue);
653
655 expected,
656 "The builder free function for "
657 << entry.first
658 << " did not create a Length with the correct value");
659 }
660}
661
662void
664{
665 auto l = Length::TryParse(1, "");
666
667 AssertFalse(l.has_value(), "TryParse returned true on bad input");
668}
669
670void
672{
673 using TestInput = std::pair<double, std::string>;
674 using TestArgs = std::pair<double, double>;
675 std::map<TestInput, TestArgs> tests{
676 {{5, "m"}, {5, 0}},
677 {{5, " m"}, {5, 0}},
678 {{5, "kilometer"}, {5e3, 0}},
679 {{5, " kilometer"}, {5e3, 0}},
680 };
681
682 for (auto& entry : tests)
683 {
684 TestInput input = entry.first;
685 TestArgs args = entry.second;
686
687 auto l = Length::TryParse(input.first, input.second);
688
689 AssertTrue(l.has_value(), "TryParse returned false when expecting true");
690
691 std::stringstream stream;
692 stream << "Parsing input (" << input.first << ", " << input.second
693 << ") returned the wrong value";
694
695 NS_TEST_ASSERT_MSG_EQ_TOL(l->GetDouble(), args.first, args.second, stream.str());
696 }
697}
698
699void
701{
702 const double value = 5;
703
704 Length original(value, Unit::Meter);
705
706 Length copy;
707 copy = original;
708
709 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), original.GetDouble(), "copy assignment failed");
710}
711
712void
714{
715 const double value = 5;
716
717 Length original(value, Unit::Meter);
718
719 Length copy;
720 copy = std::move(original);
721
722 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), value, "move assignment failed");
723}
724
725void
727{
728 Length::Quantity input(5, Unit::Kilometer);
729
730 Length l;
731 Length expected(input);
732
733 l = input;
734
735 NS_TEST_ASSERT_MSG_EQ(l, expected, "quantity assignment failed");
736}
737
738void
740{
741 const double value = 5;
742 Length one(value, Unit::Meter);
743 Length two(one);
744
745 AssertTrue(one.IsEqual(two), "IsEqual returned false for equal lengths");
746}
747
748void
750{
751 const double value = 5;
752 Length one(value, Unit::Meter);
753 Length two(value, Unit::Foot);
754
755 AssertFalse(one.IsEqual(two), "IsEqual returned true for unequal lengths");
756}
757
758void
760{
761 const double value = 5;
762 const double tolerance = 0.1;
763
764 Length one(value, Unit::Meter);
765 Length two((value + 0.1), Unit::Meter);
766
767 AssertTrue(one.IsEqual(two, tolerance), "IsEqual returned false for almost equal lengths");
768}
769
770void
772{
773 const double value = 5;
774 const double tolerance = 0.01;
775
776 Length one(value, Unit::Meter);
777 Length two((value + 0.1), Unit::Meter);
778
779 AssertFalse(one.IsEqual(two, tolerance), "IsEqual returned true for almost equal lengths");
780}
781
782void
784{
785 const double value = 5;
786
787 Length one(value, Unit::Meter);
788 Length two((value + 0.1), Unit::Meter);
789
790 AssertTrue(one.IsNotEqual(two), "IsNotEqual returned false for not equal lengths");
791}
792
793void
795{
796 const double value = 5;
797
798 Length one(value, Unit::Meter);
799 Length two(one);
800
801 AssertFalse(one.IsNotEqual(two), "IsNotEqual returned true for equal lengths");
802}
803
804void
806{
807 const double tolerance = 0.001;
808
809 Length one(5.01, Unit::Meter);
810 Length two(5.02, Unit::Meter);
811
812 AssertTrue(one.IsNotEqual(two, tolerance),
813 "IsNotEqual with tolerance returned false for not equal lengths");
814}
815
816void
818{
819 const double tolerance = 0.01;
820
821 Length one(5.01, Unit::Meter);
822 Length two(5.02, Unit::Meter);
823
824 AssertFalse(one.IsNotEqual(two, tolerance),
825 "IsNotEqual with tolerance returned true for not equal lengths");
826}
827
828void
830{
831 const double value = 5;
832
833 Length one(value, Unit::Meter);
834 Length two((value + 0.1), Unit::Meter);
835
836 AssertTrue(one.IsLess(two), "IsLess returned false for non equal lengths");
837}
838
839void
841{
842 const double value = 5;
843
844 Length one(value, Unit::Meter);
845 Length two(one);
846
847 AssertFalse(one.IsLess(two), "IsLess returned true for equal lengths");
848}
849
850void
852{
853 const double tolerance = 0.01;
854
855 Length one(5.1234, Unit::Meter);
856 Length two(5.1278, Unit::Meter);
857
858 AssertFalse(one.IsLess(two, tolerance), "IsLess with tolerance returned true");
859}
860
861void
863{
864 Length one(2.0, Unit::Meter);
865 Length two(1.0, Unit::Meter);
866
867 AssertTrue(one.IsGreater(two), "IsGreater returned false");
868}
869
870void
872{
873 Length one(2.0, Unit::Meter);
874 Length two(1.0, Unit::Meter);
875
876 AssertFalse(two.IsGreater(one), "IsGreater returned true");
877}
878
879void
881{
882 const double tolerance = 0.01;
883
884 Length one(5.1234, Unit::Meter);
885 Length two(5.1278, Unit::Meter);
886
887 AssertFalse(two.IsGreater(one, tolerance), "IsGreater returned true");
888}
889
890void
892{
893 Length l(1.0, Unit::Meter);
894
895 std::stringstream stream;
896
897 stream << l;
898
899 NS_TEST_ASSERT_MSG_EQ(stream.str(), "1 m", "unexpected output from operator<<");
900}
901
902void
904{
905 const double value = 5;
906
907 Length l;
908
909 std::stringstream stream;
910
911 stream << value << "m";
912
913 stream >> l;
914
915 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(), value, "unexpected length from operator>>");
916}
917
918template <class T>
919void
921 const T& unit,
922 const std::string& expectedOutput,
923 const std::string& context)
924{
925 const std::string msg = context + ": unexpected output when serializing length";
926
927 std::ostringstream stream;
928
929 stream << std::fixed << std::setprecision(5) << l.As(unit);
930
931 NS_TEST_ASSERT_MSG_EQ(stream.str(), expectedOutput, msg);
932}
933
934void
936{
937 Length l(1.0, Unit::Meter);
938
939 TestLengthSerialization(l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
940 TestLengthSerialization(l, Unit::Micrometer, "1000000.00000 um", "micrometers");
941 TestLengthSerialization(l, Unit::Millimeter, "1000.00000 mm", "millimeters");
942 TestLengthSerialization(l, Unit::Centimeter, "100.00000 cm", "centimeters");
943 TestLengthSerialization(l, Unit::Meter, "1.00000 m", "meters");
944 TestLengthSerialization(l, Unit::Kilometer, "0.00100 km", "kilometers");
945 TestLengthSerialization(l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
946 TestLengthSerialization(l, Unit::Inch, "39.37008 in", "inches");
947 TestLengthSerialization(l, Unit::Foot, "3.28084 ft", "feet");
948 TestLengthSerialization(l, Unit::Yard, "1.09361 yd", "yards");
949 TestLengthSerialization(l, Unit::Mile, "0.00062 mi", "miles");
950}
951
952void
954{
955 const double value = 5;
956
957 Length one(value, Unit::Meter);
958 Length two(value, Unit::Meter);
959
960 AssertTrue(one == two, "operator== returned false for equal lengths");
961}
962
963void
965{
966 const double value = 5;
967
968 Length one(value, Unit::Meter);
969 Length two(value, Unit::Kilometer);
970
971 AssertFalse(one == two, "operator== returned true for non equal lengths");
972}
973
974void
976{
977 const double value = 5;
978
979 Length one(value, Unit::Meter);
980 Length two(value, Unit::Kilometer);
981
982 AssertTrue(one != two, "operator!= returned false for non equal lengths");
983}
984
985void
987{
988 const double value = 5;
989
990 Length one(value, Unit::Meter);
991 Length two(value, Unit::Meter);
992
993 AssertFalse(one != two, "operator!= returned true for equal lengths");
994}
995
996void
998{
999 const double value = 5;
1000
1001 Length one(value, Unit::Meter);
1002 Length two(value, Unit::Kilometer);
1003
1004 AssertTrue(one < two, "operator< returned false for smaller length");
1005}
1006
1007void
1009{
1010 const double value = 5;
1011
1012 Length one(value, Unit::Meter);
1013 Length two(value, Unit::Kilometer);
1014
1015 AssertFalse(two < one, "operator< returned true for larger length");
1016}
1017
1018void
1020{
1021 const double value = 5;
1022
1023 Length one(value, Unit::Meter);
1024 Length two(value, Unit::Kilometer);
1025 Length three(one);
1026
1027 AssertTrue(one <= two, "operator<= returned false for smaller length");
1028
1029 AssertTrue(one <= three, "operator<= returned false for equal lengths");
1030}
1031
1032void
1034{
1035 const double value = 5;
1036
1037 Length one(value, Unit::Meter);
1038 Length two(value, Unit::Kilometer);
1039
1040 AssertFalse(two <= one, "operator<= returned true for larger length");
1041}
1042
1043void
1045{
1046 const double value = 5;
1047
1048 Length one(value, Unit::Meter);
1049 Length two(value, Unit::Kilometer);
1050
1051 AssertTrue(two > one, "operator> returned false for larger length");
1052}
1053
1054void
1056{
1057 const double value = 5;
1058
1059 Length one(value, Unit::Meter);
1060 Length two(value, Unit::Kilometer);
1061
1062 AssertFalse(one > two, "operator> returned true for smaller length");
1063}
1064
1065void
1067{
1068 const double value = 5;
1069
1070 Length one(value, Unit::Meter);
1071 Length two(value, Unit::Kilometer);
1072 Length three(one);
1073
1074 AssertTrue(two >= one, "operator>= returned false for larger length");
1075
1076 AssertTrue(one >= three, "operator>= returned false for equal lengths");
1077}
1078
1079void
1081{
1082 const double value = 5;
1083
1084 Length one(value, Unit::Meter);
1085 Length two(value, Unit::Kilometer);
1086
1087 AssertFalse(one >= two, "operator>= returned true for smaller length");
1088}
1089
1090void
1092{
1093 const double value = 1;
1094 const double expectedOutput = 2;
1095
1096 Length one(value, Unit::Meter);
1097 Length two(value, Unit::Meter);
1098
1099 Length result = one + two;
1100
1101 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1102 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator+ modified second operand");
1103 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1104}
1105
1106void
1108{
1109 const double value = 1;
1110 const double expectedOutput = 2;
1111
1112 Length one(value, Unit::Meter);
1113
1114 Length result = one + Length::Quantity(value, Unit::Meter);
1115
1116 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1117 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1118}
1119
1120void
1122{
1123 const double value = 1;
1124 const double expectedOutput = 2;
1125
1126 Length one(value, Unit::Meter);
1127
1128 Length result = Length::Quantity(value, Unit::Meter) + one;
1129
1130 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1131 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1132}
1133
1134void
1136{
1137 const double value = 1;
1138 const double expectedOutput = 0;
1139
1140 Length one(value, Unit::Meter);
1141 Length two(value, Unit::Meter);
1142
1143 Length result = one - two;
1144
1145 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1146 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator- modified second operand");
1147 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1148}
1149
1150void
1152{
1153 const double value = 1;
1154 const double expectedOutput = 0;
1155
1156 Length one(value, Unit::Meter);
1157
1158 Length result = one - Length::Quantity(value, Unit::Meter);
1159
1160 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1161 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1162}
1163
1164void
1166{
1167 const double value = 1;
1168 const double expectedOutput = 0;
1169
1170 Length one(value, Unit::Meter);
1171
1172 Length result = Length::Quantity(value, Unit::Meter) - one;
1173
1174 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified second operand");
1175 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1176}
1177
1178void
1180{
1181 const double value = 1;
1182 const double scalar = 5;
1183 const double expectedOutput = value * scalar;
1184
1185 Length one(value, Unit::Meter);
1186 Length result = one * scalar;
1187
1188 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified first operand");
1189 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1190}
1191
1192void
1194{
1195 const double value = 1;
1196 const double scalar = 5;
1197 const double expectedOutput = value * scalar;
1198
1199 Length one(value, Unit::Meter);
1200 Length result = scalar * one;
1201
1202 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified second operand");
1203 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1204}
1205
1206void
1208{
1209 const double value = 10;
1210 const double scalar = 5;
1211 const double expectedOutput = value / scalar;
1212
1213 Length one(value, Unit::Meter);
1214 Length result = one / scalar;
1215
1216 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator/ modified first operand");
1217 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator/ returned incorrect value");
1218}
1219
1220void
1222{
1223 const double valueOne = 100;
1224 const double valueTwo = 2;
1225 const double expectedOutput = valueOne / valueTwo;
1226
1227 Length one(valueOne, Unit::Meter);
1228 Length two(valueTwo, Unit::Meter);
1229
1230 double result = one / two;
1231
1232 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), valueOne, "operator/ modified first operand");
1233 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), valueTwo, "operator/ modified second operand");
1234 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "operator/ returned incorrect value");
1235}
1236
1237void
1239{
1240 const double value = 1;
1241
1242 Length one(value, Unit::Meter);
1243 Length two;
1244
1245 double result = one / two;
1246
1247 AssertTrue(std::isnan(result), "operator/ did not return NaN when dividing by zero");
1248}
1249
1250void
1252{
1253 const double topValue = 100;
1254 const double bottomValue = 20;
1255 const int64_t expectedOutput = 5;
1256
1257 Length numerator(topValue, Unit::Meter);
1258 Length denominator(bottomValue, Unit::Meter);
1259
1260 auto result = Div(numerator, denominator);
1261
1262 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1263}
1264
1265void
1267{
1268 const double topValue = 100;
1269 const double bottomValue = 20;
1270 const int64_t expectedOutput = 5;
1271 const int64_t expectedRemainder = 0;
1272
1273 Length numerator(topValue, Unit::Meter);
1274 Length denominator(bottomValue, Unit::Meter);
1275 Length remainder;
1276
1277 auto result = Div(numerator, denominator, &remainder);
1278
1279 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1280 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1281 expectedRemainder,
1282 "Div() returned an incorrect remainder");
1283}
1284
1285void
1287{
1288 const double topValue = 110;
1289 const double bottomValue = 20;
1290 const int64_t expectedOutput = 5;
1291 const int64_t expectedRemainder = 10;
1292
1293 Length numerator(topValue, Unit::Meter);
1294 Length denominator(bottomValue, Unit::Meter);
1295 Length remainder;
1296
1297 auto result = Div(numerator, denominator, &remainder);
1298
1299 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1300 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1301 expectedRemainder,
1302 "Div() returned an incorrect remainder");
1303}
1304
1305void
1307{
1308 Length numerator(10, Unit::Meter);
1309 Length denominator(2, Unit::Meter);
1310
1311 auto result = Mod(numerator, denominator);
1312
1313 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), 0, "Mod() returned a non zero value");
1314}
1315
1316void
1318{
1319 Length numerator(14, Unit::Meter);
1320 Length denominator(3, Unit::Meter);
1321 const double expectedValue = 2;
1322
1323 auto result = Mod(numerator, denominator);
1324
1325 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedValue, "Mod() returned the wrong value");
1326}
1327
1328void
1330{
1332
1334
1336
1338
1340
1342
1354
1355#ifdef HAVE_BOOST_UNITS
1356 TestConstructLengthFromBoostUnits();
1357#endif
1358
1360
1363
1367
1382
1384
1386
1399
1411
1415
1418}
1419
1420/**
1421 * \ingroup length-tests
1422 *
1423 * Test case for LengthValue attribute
1424 */
1426{
1427 public:
1428 /**
1429 * Default Constructor
1430 */
1432 : TestCase("length-value-tests")
1433 {
1434 }
1435
1436 /**
1437 * Destructor
1438 */
1440 {
1441 }
1442
1443 private:
1444 /// Class with Length attribute
1445 class TestObject : public Object
1446 {
1447 public:
1448 /**
1449 * \brief Get the type ID.
1450 * \return The object TypeId.
1451 */
1452 static TypeId GetTypeId();
1453
1455 : m_length()
1456 {
1457 }
1458
1459 ~TestObject() override
1460 {
1461 }
1462
1463 private:
1464 Length m_length; //!< Length object
1465 };
1466
1467 private:
1468 /**
1469 * Test that a LengthValue can be constructed from a Length instance
1470 */
1472
1473 /**
1474 * Test that a LengthValue can be serialized to a string
1475 */
1477
1478 /**
1479 * Test that a LengthValue can be deserialized from a string
1480 */
1482
1483 /**
1484 * Test that a LengthValue works as an attribute
1485 */
1486 void TestObjectAttribute();
1487
1488 /**
1489 * Test that a StringValue is converted to LengthValue
1490 */
1492
1493 // Inherited function
1494 void DoRun() override;
1495};
1496
1497TypeId
1499{
1500 static TypeId tid = TypeId("LengthValueTestCase::TestObject")
1501 .SetParent<Object>()
1502 .SetGroupName("Test")
1503 .AddConstructor<TestObject>()
1504 .AddAttribute("Length",
1505 "Length value",
1506 LengthValue(),
1509
1510 return tid;
1511}
1512
1513void
1515{
1516 Length l = KiloMeters(2);
1517 LengthValue value(l);
1518
1519 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value");
1520}
1521
1522void
1524{
1526
1527 Length l = KiloMeters(2);
1528 LengthValue value(l);
1529
1530 std::string output = value.SerializeToString(checker);
1531
1532 NS_TEST_ASSERT_MSG_EQ(output, "2000 m", "Length attribute serialization has wrong output");
1533}
1534
1535void
1537{
1539
1540 Length l = KiloMeters(2);
1541 std::ostringstream stream;
1542 stream << l;
1543
1544 LengthValue value;
1545 bool result = value.DeserializeFromString(stream.str(), checker);
1546
1547 NS_TEST_ASSERT_MSG_EQ(result, true, "Length attribute deserialization failed");
1548 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value after deserialization");
1549}
1550
1551void
1553{
1554 Length expected(5, Unit::Kilometer);
1555 Ptr<TestObject> obj = CreateObject<TestObject>();
1556
1557 obj->SetAttribute("Length", LengthValue(expected));
1558
1559 LengthValue val;
1560 obj->GetAttribute("Length", val);
1561
1562 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1563}
1564
1565void
1567{
1568 Length expected(5, Unit::Kilometer);
1569 Ptr<TestObject> obj = CreateObject<TestObject>();
1570
1571 std::stringstream stream;
1572 stream << expected.As(Unit::Kilometer);
1573
1574 obj->SetAttribute("Length", StringValue(stream.str()));
1575
1576 LengthValue val;
1577 obj->GetAttribute("Length", val);
1578
1579 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1580}
1581
1582void
1584{
1590}
1591
1592/**
1593 * \ingroup length-tests
1594 * The Test Suite that runs the test case
1595 */
1597{
1598 public:
1599 /**
1600 * Default Constructor
1601 */
1603};
1604
1606 : TestSuite("length")
1607{
1608 AddTestCase(new LengthTestCase(), TestCase::Duration::QUICK);
1609 AddTestCase(new LengthValueTestCase(), TestCase::Duration::QUICK);
1610}
1611
1612/**
1613 * LengthTestSuite instance
1614 */
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.
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.
Definition: length.h:272
double Value() const
The value of the quantity.
Definition: length.h:320
Represents a length in meters.
Definition: length.h:244
double GetDouble() const
Current length value.
Definition: length.cc:381
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
Definition: length.cc:357
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition: length.cc:318
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:387
static std::optional< Length > TryParse(double value, const std::string &unit)
Attempt to construct a Length object from a value and a unit string.
Definition: length.cc:244
Unit
Units of length in various measurement systems that are supported by the Length class.
Definition: length.h:251
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
Definition: length.cc:341
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:333
AttributeValue implementation for Length.
Definition: length.h:623
Length Get() const
Definition: length.cc:241
A base class which provides memory management and object aggregation.
Definition: object.h:89
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:77
Hold variables of type string.
Definition: string.h:56
encapsulates test code
Definition: test.h:1061
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:301
A suite of tests to run.
Definition: test.h:1268
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Ptr< const AttributeChecker > MakeLengthChecker()
Definition: length.cc:241
Ptr< const AttributeAccessor > MakeLengthAccessor(T1 a1)
Definition: length.h:623
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:817
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:799
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:823
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:841
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:835
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:501
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:793
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:847
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:811
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:805
int64_t Div(const Length &numerator, const Length &denominator, Length *remainder)
Calculate how many times numerator can be split into denominator sized pieces.
Definition: length.cc:482
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:787
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:829
#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.
Definition: test.h:145
#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...
Definition: test.h:338
static LengthTestSuite gLengthTestSuite
LengthTestSuite instance.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
-ray-to-three-gpp-ch-calibration