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 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Mathew Bielejeski<bielejeski1@llnl.gov>
7 */
8
9#include "ns3/length.h"
10#include "ns3/log.h"
11#include "ns3/object.h"
12#include "ns3/string.h"
13#include "ns3/test.h"
14
15#ifdef HAVE_BOOST
16#include <boost/units/base_units/us/foot.hpp>
17#include <boost/units/systems/si.hpp>
18#include <boost/units/systems/si/prefixes.hpp>
19#endif
20
21#include <array>
22#include <cmath>
23#include <functional>
24#include <initializer_list>
25#include <iomanip>
26#include <limits>
27#include <map>
28#include <sstream>
29#include <string>
30
31/**
32 * \file
33 * \ingroup length-tests
34 * Length class tests.
35 */
36
37/**
38 * \ingroup core-tests length
39 * \defgroup length-tests Length test suite
40 */
41
42using namespace ns3;
43
44/**
45 * Save some typing by defining a short alias for Length::Unit
46 */
48
49/**
50 * Implements tests for the Length class
51 */
53{
54 public:
55 /**
56 * Constructor
57 */
59 : TestCase("length-tests")
60 {
61 }
62
63 /**
64 * Destructor
65 */
66 ~LengthTestCase() override = default;
67
68 protected:
69 /**
70 * Helper function to compare results with false
71 *
72 * \param condition The boolean condition to test
73 * \param msg The message to print if the test fails
74 */
75 void AssertFalse(bool condition, std::string msg)
76 {
77 NS_TEST_ASSERT_MSG_EQ(condition, false, msg);
78 }
79
80 /**
81 * Helper function to compare results with true
82 *
83 * \param condition The boolean condition to test
84 * \param msg The message to print if the test fails
85 */
86 void AssertTrue(bool condition, std::string msg)
87 {
88 NS_TEST_ASSERT_MSG_EQ(condition, true, msg);
89 }
90
91 private:
92 /**
93 * Test that a default constructed Length object has a value of 0
94 */
96
97 /**
98 * Test that a Length object can be constructed from a Quantity object
99 */
101
102 /**
103 * Test that a Length object constructed from various SI units has the
104 * correct value in meters
105 */
107
108 /**
109 * Test that a Length object constructed from various US units has the
110 * correct value in meters
111 */
113
114 /**
115 * Test that the value from one length is copied to another
116 * using the copy constructor.
117 */
119
120 /**
121 * Test that the value from one length is copied to another
122 * using the move constructor.
123 */
125
126 /**
127 * Test that a length object can be constructed from a string
128 * \param unitValue //!< Value to test.
129 * \param meterValue //!< Reference value [m].
130 * \param tolerance //!< Tolerance.
131 * \param symbols //!< Unit symbols.
132 */
133 void TestConstructLengthFromString(double unitValue,
134 double meterValue,
135 double tolerance,
136 const std::initializer_list<std::string>& symbols);
137
138 /**
139 * Test that a length object can be constructed from a string
140 * @{
141 */
153 /** @} */
154
155#ifdef HAVE_BOOST_UNITS
156 /**
157 * Test construction from boost::units
158 * @{
159 */
160 void TestConstructLengthFromBoostUnits();
161 void TestConstructLengthFromBoostUnitsMeters();
162 void TestConstructLengthFromBoostUnitsKiloMeters();
163 void TestConstructLengthFromBoostUnitsFeet();
164 /** @} */
165#endif
166
167 /**
168 * Test constructing length objects using the builder free functions
169 * @{
170 */
172 /** @} */
173
174 /**
175 * Test the TryParse function returns false on bad input
176 */
178
179 /**
180 * Test the TryParse function returns true on success
181 */
183
184 /**
185 * Test that a length object can be updated by assignment from another
186 * length object
187 */
188 void TestCopyAssignment();
189
190 /**
191 * Test that a length object can be updated by assignment from a moved
192 * length object
193 */
194 void TestMoveAssignment();
195
196 /**
197 * Test that a length object can be updated by assignment from a quantity
198 */
200
201 /**
202 * Test member comparison operators
203 * @{
204 */
219 /** @} */
220
221 /**
222 * Test writing length object to a stream produces the expected output
223 */
225
226 /**
227 * Test reading length object from a stream produces the expected length
228 * value
229 */
231
232 /**
233 * Generic function for testing serialization of a Length object in
234 * various units
235 *
236 * \tparam T Type of the length unit that should be output during serialization
237 *
238 * \param l Length object to serialize
239 * \param unit Unit that the length value will be converted to before serialization
240 * \param expectedOutput Expected result of the serialization
241 * \param context Included in the error message if the test fails
242 */
243 template <class T>
244 void TestLengthSerialization(const Length& l,
245 const T& unit,
246 const std::string& expectedOutput,
247 const std::string& context);
248
249 /**
250 * Test serializing a length object to all of the supported unit types
251 */
253
254 /**
255 * Test free function comparison operators
256 * @{
257 */
270 /** @} */
271
272 /**
273 * Test arithmetic operations
274 * @{
275 */
287 /** @} */
288
289 /**
290 * Test Div function
291 * @{
292 */
296 /** @} */
297
298 /**
299 * Test Mod function
300 * @{
301 */
302 void TestModReturnsZero();
304 /** @} */
305
306 void DoRun() override;
307};
308
309void
311{
312 Length l;
313
314 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(), 0, "Default value of Length is not 0");
315}
316
317void
319{
320 const Length::Quantity VALUE(5.0, Unit::Meter);
321
322 Length l(VALUE);
323
325 VALUE.Value(),
326 "length constructed from meters has wrong value");
327}
328
329void
331{
332 using TestEntry = std::tuple<Length, std::string>;
333
334 const double expectedMeters = 1;
335 const std::initializer_list<TestEntry> inputs{
336 std::make_tuple(Length(1e9, Unit::Nanometer), "nanometer"),
337 std::make_tuple(Length(1e6, Unit::Micrometer), "micrometer"),
338 std::make_tuple(Length(1e3, Unit::Millimeter), "millimeter"),
339 std::make_tuple(Length(1e2, Unit::Centimeter), "centimeter"),
340 std::make_tuple(Length(1e-3, Unit::Kilometer), "kilometer"),
341 std::make_tuple(Length((1 / 1852.0), Unit::NauticalMile), "nautical_mile")};
342
343 for (const TestEntry& entry : inputs)
344 {
345 const Length& l = std::get<0>(entry);
346 const std::string& context = std::get<1>(entry);
347
349 expectedMeters,
350 context << ": constructed length from SI unit has wrong value");
351 }
352}
353
354void
356{
357 using TestEntry = std::tuple<Length, std::string>;
358
359 const double expectedMeters = 0.3048;
360 const double tolerance = 0.0001;
361
362 const std::initializer_list<TestEntry> inputs{
363 std::make_tuple(Length(12.0, Unit::Inch), "inch"),
364 std::make_tuple(Length(1.0, Unit::Foot), "foot"),
365 std::make_tuple(Length((1 / 3.0), Unit::Yard), "yard"),
366 std::make_tuple(Length((1 / 5280.0), Unit::Mile), "mile"),
367 };
368
369 for (const TestEntry& entry : inputs)
370 {
371 const Length& l = std::get<0>(entry);
372 const std::string& context = std::get<1>(entry);
373
375 expectedMeters,
376 tolerance,
377 "constructed length from US unit (" << context
378 << ") has wrong value");
379 }
380}
381
382void
384{
385 const double value = 5;
386 Length original(value, Unit::Meter);
387
388 Length copy(original);
389
391 original.GetDouble(),
392 "copy constructed length has wrong value");
393}
394
395void
397{
398 const double value = 5;
399 Length original(value, Unit::Meter);
400
401 Length copy(std::move(original));
402
403 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), value, "move constructed length has wrong value");
404}
405
406void
408 double meterValue,
409 double tolerance,
410 const std::initializer_list<std::string>& symbols)
411{
412 const std::array<std::string, 2> SEPARATORS{{"", " "}};
413
414 for (const std::string& symbol : symbols)
415 {
416 for (const std::string& separator : SEPARATORS)
417 {
418 std::ostringstream stream;
419
420 stream << unitValue << separator << symbol;
421
422 Length l(stream.str());
423
424 std::ostringstream msg;
425 msg << "string constructed length has wrong value: '" << stream.str() << "'";
426
427 NS_TEST_ASSERT_MSG_EQ_TOL(l.GetDouble(), meterValue, tolerance, msg.str());
428 }
429 }
430}
431
432void
434{
435 const double value = 5;
436
437 TestConstructLengthFromString(value, value, 0, {"m", "meter", "meters", "metre", "metres"});
438}
439
440void
442{
443 const double value = 5;
444 const double expectedValue = 5e-9;
445
447 expectedValue,
448 0,
449 {"nm", "nanometer", "nanometers", "nanometre", "nanometres"});
450}
451
452void
454{
455 const double value = 5;
456 const double expectedValue = 5e-6;
457 const double tolerance = 1e-7;
458
460 expectedValue,
461 tolerance,
462 {"um", "micrometer", "micrometers", "micrometre", "micrometres"});
463}
464
465void
467{
468 const double value = 5;
469 const double expectedValue = 5e-3;
470 const double tolerance = 1e-4;
471
473 expectedValue,
474 tolerance,
475 {"mm", "millimeter", "millimeters", "millimetre", "millimetres"});
476}
477
478void
480{
481 const double value = 5;
482 const double expectedValue = 5e-2;
483 const double tolerance = 1e-3;
484
486 expectedValue,
487 tolerance,
488 {"cm", "centimeter", "centimeters", "centimetre", "centimetres"});
489}
490
491void
493{
494 const double value = 5;
495 const double expectedValue = 5e3;
496
498 expectedValue,
499 0,
500 {"km", "kilometer", "kilometers", "kilometre", "kilometres"});
501}
502
503void
505{
506 const double value = 5;
507 const double expectedValue = 9260;
508
510 expectedValue,
511 0,
512 {"nmi", "nautical mile", "nautical miles"});
513}
514
515void
517{
518 const double value = 5;
519 const double expectedValue = 0.127;
520 const double tolerance = 1e-4;
521
522 TestConstructLengthFromString(value, expectedValue, tolerance, {"in", "inch", "inches"});
523}
524
525void
527{
528 const double value = 5;
529 const double expectedValue = 1.524;
530 const double tolerance = 1e-4;
531
532 TestConstructLengthFromString(value, expectedValue, tolerance, {"ft", "foot", "feet"});
533}
534
535void
537{
538 const double value = 5;
539 const double expectedValue = 4.572;
540 const double tolerance = 1e-4;
541
542 TestConstructLengthFromString(value, expectedValue, tolerance, {"yd", "yard", "yards"});
543}
544
545void
547{
548 const double value = 5;
549 const double expectedValue = 8046.72;
550 const double tolerance = 1e-3;
551
552 TestConstructLengthFromString(value, expectedValue, tolerance, {"mi", "mile", "miles"});
553}
554
555#ifdef HAVE_BOOST_UNITS
556void
557LengthTestCase::TestConstructLengthFromBoostUnits()
558{
559 TestConstructLengthFromBoostUnitsMeters();
560 TestConstructLengthFromBoostUnitsKiloMeters();
561 TestConstructLengthFromBoostUnitsFeet();
562}
563
564void
565LengthTestCase::TestConstructLengthFromBoostUnitsMeters()
566{
567 namespace bu = boost::units;
568
569 auto meters = 5 * bu::si::meter;
570
571 Length l(meters);
572
573 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(),
574 meters.value(),
575 "Construction from boost::units meters produced "
576 "incorrect value");
577}
578
579void
580LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters()
581{
582 namespace bu = boost::units;
583 auto kilometer = bu::si::kilo * bu::si::meter;
584
585 const double expectedValue = 5000;
586 auto quantity = 5 * kilometer;
587
588 Length l(quantity);
589
590 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(),
591 expectedValue,
592 "Construction from boost::units kilometers produced "
593 "incorrect value");
594}
595
596void
597LengthTestCase::TestConstructLengthFromBoostUnitsFeet()
598{
599 namespace bu = boost::units;
600
601 bu::us::foot_base_unit::unit_type Foot;
602
603 const double expectedValue = 3.048;
604 auto feet = 10 * Foot;
605
606 Length l(feet);
607
608 NS_TEST_ASSERT_MSG_EQ_TOL(l.GetDouble(),
609 expectedValue,
610 0.001,
611 "Construction from boost::units foot produced "
612 "incorrect value");
613}
614#endif
615
616void
618{
619 using Builder = std::function<Length(double)>;
620
621 double inputValue = 10;
622
623 std::map<Unit, Builder> TESTDATA{
624 {Unit::Nanometer, NanoMeters},
625 {Unit::Micrometer, MicroMeters},
626 {Unit::Millimeter, MilliMeters},
627 {Unit::Centimeter, CentiMeters},
628 {Unit::Meter, Meters},
629 {Unit::Kilometer, KiloMeters},
630 {Unit::NauticalMile, NauticalMiles},
631 {Unit::Inch, Inches},
632 {Unit::Foot, Feet},
633 {Unit::Yard, Yards},
634 {Unit::Mile, Miles},
635 };
636
637 for (auto& entry : TESTDATA)
638 {
639 Length expected(inputValue, entry.first);
640
641 Length output = entry.second(inputValue);
642
644 expected,
645 "The builder free function for "
646 << entry.first
647 << " did not create a Length with the correct value");
648 }
649}
650
651void
653{
654 auto l = Length::TryParse(1, "");
655
656 AssertFalse(l.has_value(), "TryParse returned true on bad input");
657}
658
659void
661{
662 using TestInput = std::pair<double, std::string>;
663 using TestArgs = std::pair<double, double>;
664 std::map<TestInput, TestArgs> tests{
665 {{5, "m"}, {5, 0}},
666 {{5, " m"}, {5, 0}},
667 {{5, "kilometer"}, {5e3, 0}},
668 {{5, " kilometer"}, {5e3, 0}},
669 };
670
671 for (auto& entry : tests)
672 {
673 TestInput input = entry.first;
674 TestArgs args = entry.second;
675
676 auto l = Length::TryParse(input.first, input.second);
677
678 AssertTrue(l.has_value(), "TryParse returned false when expecting true");
679
680 std::stringstream stream;
681 stream << "Parsing input (" << input.first << ", " << input.second
682 << ") returned the wrong value";
683
684 NS_TEST_ASSERT_MSG_EQ_TOL(l->GetDouble(), args.first, args.second, stream.str());
685 }
686}
687
688void
690{
691 const double value = 5;
692
693 Length original(value, Unit::Meter);
694
695 Length copy;
696 copy = original;
697
698 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), original.GetDouble(), "copy assignment failed");
699}
700
701void
703{
704 const double value = 5;
705
706 Length original(value, Unit::Meter);
707
708 Length copy;
709 copy = std::move(original);
710
711 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), value, "move assignment failed");
712}
713
714void
716{
717 Length::Quantity input(5, Unit::Kilometer);
718
719 Length l;
720 Length expected(input);
721
722 l = input;
723
724 NS_TEST_ASSERT_MSG_EQ(l, expected, "quantity assignment failed");
725}
726
727void
729{
730 const double value = 5;
731 Length one(value, Unit::Meter);
732 Length two(one);
733
734 AssertTrue(one.IsEqual(two), "IsEqual returned false for equal lengths");
735}
736
737void
739{
740 const double value = 5;
741 Length one(value, Unit::Meter);
742 Length two(value, Unit::Foot);
743
744 AssertFalse(one.IsEqual(two), "IsEqual returned true for unequal lengths");
745}
746
747void
749{
750 const double value = 5;
751 const double tolerance = 0.1;
752
753 Length one(value, Unit::Meter);
754 Length two((value + 0.1), Unit::Meter);
755
756 AssertTrue(one.IsEqual(two, tolerance), "IsEqual returned false for almost equal lengths");
757}
758
759void
761{
762 const double value = 5;
763 const double tolerance = 0.01;
764
765 Length one(value, Unit::Meter);
766 Length two((value + 0.1), Unit::Meter);
767
768 AssertFalse(one.IsEqual(two, tolerance), "IsEqual returned true for almost equal lengths");
769}
770
771void
773{
774 const double value = 5;
775
776 Length one(value, Unit::Meter);
777 Length two((value + 0.1), Unit::Meter);
778
779 AssertTrue(one.IsNotEqual(two), "IsNotEqual returned false for not equal lengths");
780}
781
782void
784{
785 const double value = 5;
786
787 Length one(value, Unit::Meter);
788 Length two(one);
789
790 AssertFalse(one.IsNotEqual(two), "IsNotEqual returned true for equal lengths");
791}
792
793void
795{
796 const double tolerance = 0.001;
797
798 Length one(5.01, Unit::Meter);
799 Length two(5.02, Unit::Meter);
800
801 AssertTrue(one.IsNotEqual(two, tolerance),
802 "IsNotEqual with tolerance returned false for not equal lengths");
803}
804
805void
807{
808 const double tolerance = 0.01;
809
810 Length one(5.01, Unit::Meter);
811 Length two(5.02, Unit::Meter);
812
813 AssertFalse(one.IsNotEqual(two, tolerance),
814 "IsNotEqual with tolerance returned true for not equal lengths");
815}
816
817void
819{
820 const double value = 5;
821
822 Length one(value, Unit::Meter);
823 Length two((value + 0.1), Unit::Meter);
824
825 AssertTrue(one.IsLess(two), "IsLess returned false for non equal lengths");
826}
827
828void
830{
831 const double value = 5;
832
833 Length one(value, Unit::Meter);
834 Length two(one);
835
836 AssertFalse(one.IsLess(two), "IsLess returned true for equal lengths");
837}
838
839void
841{
842 const double tolerance = 0.01;
843
844 Length one(5.1234, Unit::Meter);
845 Length two(5.1278, Unit::Meter);
846
847 AssertFalse(one.IsLess(two, tolerance), "IsLess with tolerance returned true");
848}
849
850void
852{
853 Length one(2.0, Unit::Meter);
854 Length two(1.0, Unit::Meter);
855
856 AssertTrue(one.IsGreater(two), "IsGreater returned false");
857}
858
859void
861{
862 Length one(2.0, Unit::Meter);
863 Length two(1.0, Unit::Meter);
864
865 AssertFalse(two.IsGreater(one), "IsGreater returned true");
866}
867
868void
870{
871 const double tolerance = 0.01;
872
873 Length one(5.1234, Unit::Meter);
874 Length two(5.1278, Unit::Meter);
875
876 AssertFalse(two.IsGreater(one, tolerance), "IsGreater returned true");
877}
878
879void
881{
882 Length l(1.0, Unit::Meter);
883
884 std::stringstream stream;
885
886 stream << l;
887
888 NS_TEST_ASSERT_MSG_EQ(stream.str(), "1 m", "unexpected output from operator<<");
889}
890
891void
893{
894 const double value = 5;
895
896 Length l;
897
898 std::stringstream stream;
899
900 stream << value << "m";
901
902 stream >> l;
903
904 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(), value, "unexpected length from operator>>");
905}
906
907template <class T>
908void
910 const T& unit,
911 const std::string& expectedOutput,
912 const std::string& context)
913{
914 const std::string msg = context + ": unexpected output when serializing length";
915
916 std::ostringstream stream;
917
918 stream << std::fixed << std::setprecision(5) << l.As(unit);
919
920 NS_TEST_ASSERT_MSG_EQ(stream.str(), expectedOutput, msg);
921}
922
923void
925{
926 Length l(1.0, Unit::Meter);
927
928 TestLengthSerialization(l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
929 TestLengthSerialization(l, Unit::Micrometer, "1000000.00000 um", "micrometers");
930 TestLengthSerialization(l, Unit::Millimeter, "1000.00000 mm", "millimeters");
931 TestLengthSerialization(l, Unit::Centimeter, "100.00000 cm", "centimeters");
932 TestLengthSerialization(l, Unit::Meter, "1.00000 m", "meters");
933 TestLengthSerialization(l, Unit::Kilometer, "0.00100 km", "kilometers");
934 TestLengthSerialization(l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
935 TestLengthSerialization(l, Unit::Inch, "39.37008 in", "inches");
936 TestLengthSerialization(l, Unit::Foot, "3.28084 ft", "feet");
937 TestLengthSerialization(l, Unit::Yard, "1.09361 yd", "yards");
938 TestLengthSerialization(l, Unit::Mile, "0.00062 mi", "miles");
939}
940
941void
943{
944 const double value = 5;
945
946 Length one(value, Unit::Meter);
947 Length two(value, Unit::Meter);
948
949 AssertTrue(one == two, "operator== returned false for equal lengths");
950}
951
952void
954{
955 const double value = 5;
956
957 Length one(value, Unit::Meter);
958 Length two(value, Unit::Kilometer);
959
960 AssertFalse(one == two, "operator== returned true for non 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 AssertTrue(one != two, "operator!= returned false 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::Meter);
981
982 AssertFalse(one != two, "operator!= returned true for equal lengths");
983}
984
985void
987{
988 const double value = 5;
989
990 Length one(value, Unit::Meter);
991 Length two(value, Unit::Kilometer);
992
993 AssertTrue(one < two, "operator< returned false for smaller length");
994}
995
996void
998{
999 const double value = 5;
1000
1001 Length one(value, Unit::Meter);
1002 Length two(value, Unit::Kilometer);
1003
1004 AssertFalse(two < one, "operator< returned true for larger length");
1005}
1006
1007void
1009{
1010 const double value = 5;
1011
1012 Length one(value, Unit::Meter);
1013 Length two(value, Unit::Kilometer);
1014 Length three(one);
1015
1016 AssertTrue(one <= two, "operator<= returned false for smaller length");
1017
1018 AssertTrue(one <= three, "operator<= returned false for equal lengths");
1019}
1020
1021void
1023{
1024 const double value = 5;
1025
1026 Length one(value, Unit::Meter);
1027 Length two(value, Unit::Kilometer);
1028
1029 AssertFalse(two <= one, "operator<= returned true for larger length");
1030}
1031
1032void
1034{
1035 const double value = 5;
1036
1037 Length one(value, Unit::Meter);
1038 Length two(value, Unit::Kilometer);
1039
1040 AssertTrue(two > one, "operator> returned false 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 AssertFalse(one > two, "operator> returned true for smaller length");
1052}
1053
1054void
1056{
1057 const double value = 5;
1058
1059 Length one(value, Unit::Meter);
1060 Length two(value, Unit::Kilometer);
1061 Length three(one);
1062
1063 AssertTrue(two >= one, "operator>= returned false for larger length");
1064
1065 AssertTrue(one >= three, "operator>= returned false for equal lengths");
1066}
1067
1068void
1070{
1071 const double value = 5;
1072
1073 Length one(value, Unit::Meter);
1074 Length two(value, Unit::Kilometer);
1075
1076 AssertFalse(one >= two, "operator>= returned true for smaller length");
1077}
1078
1079void
1081{
1082 const double value = 1;
1083 const double expectedOutput = 2;
1084
1085 Length one(value, Unit::Meter);
1086 Length two(value, Unit::Meter);
1087
1088 Length result = one + two;
1089
1090 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1091 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator+ modified second operand");
1092 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1093}
1094
1095void
1097{
1098 const double value = 1;
1099 const double expectedOutput = 2;
1100
1101 Length one(value, Unit::Meter);
1102
1103 Length result = one + Length::Quantity(value, Unit::Meter);
1104
1105 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1106 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1107}
1108
1109void
1111{
1112 const double value = 1;
1113 const double expectedOutput = 2;
1114
1115 Length one(value, Unit::Meter);
1116
1117 Length result = Length::Quantity(value, Unit::Meter) + one;
1118
1119 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1120 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1121}
1122
1123void
1125{
1126 const double value = 1;
1127 const double expectedOutput = 0;
1128
1129 Length one(value, Unit::Meter);
1130 Length two(value, Unit::Meter);
1131
1132 Length result = one - two;
1133
1134 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1135 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator- modified second operand");
1136 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1137}
1138
1139void
1141{
1142 const double value = 1;
1143 const double expectedOutput = 0;
1144
1145 Length one(value, Unit::Meter);
1146
1147 Length result = one - Length::Quantity(value, Unit::Meter);
1148
1149 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1150 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1151}
1152
1153void
1155{
1156 const double value = 1;
1157 const double expectedOutput = 0;
1158
1159 Length one(value, Unit::Meter);
1160
1161 Length result = Length::Quantity(value, Unit::Meter) - one;
1162
1163 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified second operand");
1164 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1165}
1166
1167void
1169{
1170 const double value = 1;
1171 const double scalar = 5;
1172 const double expectedOutput = value * scalar;
1173
1174 Length one(value, Unit::Meter);
1175 Length result = one * scalar;
1176
1177 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified first operand");
1178 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1179}
1180
1181void
1183{
1184 const double value = 1;
1185 const double scalar = 5;
1186 const double expectedOutput = value * scalar;
1187
1188 Length one(value, Unit::Meter);
1189 Length result = scalar * one;
1190
1191 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified second operand");
1192 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1193}
1194
1195void
1197{
1198 const double value = 10;
1199 const double scalar = 5;
1200 const double expectedOutput = value / scalar;
1201
1202 Length one(value, Unit::Meter);
1203 Length result = one / scalar;
1204
1205 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator/ modified first operand");
1206 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator/ returned incorrect value");
1207}
1208
1209void
1211{
1212 const double valueOne = 100;
1213 const double valueTwo = 2;
1214 const double expectedOutput = valueOne / valueTwo;
1215
1216 Length one(valueOne, Unit::Meter);
1217 Length two(valueTwo, Unit::Meter);
1218
1219 double result = one / two;
1220
1221 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), valueOne, "operator/ modified first operand");
1222 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), valueTwo, "operator/ modified second operand");
1223 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "operator/ returned incorrect value");
1224}
1225
1226void
1228{
1229 const double value = 1;
1230
1231 Length one(value, Unit::Meter);
1232 Length two;
1233
1234 double result = one / two;
1235
1236 AssertTrue(std::isnan(result), "operator/ did not return NaN when dividing by zero");
1237}
1238
1239void
1241{
1242 const double topValue = 100;
1243 const double bottomValue = 20;
1244 const int64_t expectedOutput = 5;
1245
1246 Length numerator(topValue, Unit::Meter);
1247 Length denominator(bottomValue, Unit::Meter);
1248
1249 auto result = Div(numerator, denominator);
1250
1251 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1252}
1253
1254void
1256{
1257 const double topValue = 100;
1258 const double bottomValue = 20;
1259 const int64_t expectedOutput = 5;
1260 const int64_t expectedRemainder = 0;
1261
1262 Length numerator(topValue, Unit::Meter);
1263 Length denominator(bottomValue, Unit::Meter);
1264 Length remainder;
1265
1266 auto result = Div(numerator, denominator, &remainder);
1267
1268 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1269 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1270 expectedRemainder,
1271 "Div() returned an incorrect remainder");
1272}
1273
1274void
1276{
1277 const double topValue = 110;
1278 const double bottomValue = 20;
1279 const int64_t expectedOutput = 5;
1280 const int64_t expectedRemainder = 10;
1281
1282 Length numerator(topValue, Unit::Meter);
1283 Length denominator(bottomValue, Unit::Meter);
1284 Length remainder;
1285
1286 auto result = Div(numerator, denominator, &remainder);
1287
1288 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1289 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1290 expectedRemainder,
1291 "Div() returned an incorrect remainder");
1292}
1293
1294void
1296{
1297 Length numerator(10, Unit::Meter);
1298 Length denominator(2, Unit::Meter);
1299
1300 auto result = Mod(numerator, denominator);
1301
1302 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), 0, "Mod() returned a non zero value");
1303}
1304
1305void
1307{
1308 Length numerator(14, Unit::Meter);
1309 Length denominator(3, Unit::Meter);
1310 const double expectedValue = 2;
1311
1312 auto result = Mod(numerator, denominator);
1313
1314 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedValue, "Mod() returned the wrong value");
1315}
1316
1317void
1319{
1321
1323
1325
1327
1329
1331
1343
1344#ifdef HAVE_BOOST_UNITS
1345 TestConstructLengthFromBoostUnits();
1346#endif
1347
1349
1352
1356
1371
1373
1375
1388
1400
1404
1407}
1408
1409/**
1410 * \ingroup length-tests
1411 *
1412 * Test case for LengthValue attribute
1413 */
1415{
1416 public:
1417 /**
1418 * Default Constructor
1419 */
1421 : TestCase("length-value-tests")
1422 {
1423 }
1424
1425 /**
1426 * Destructor
1427 */
1429 {
1430 }
1431
1432 private:
1433 /// Class with Length attribute
1434 class TestObject : public Object
1435 {
1436 public:
1437 /**
1438 * \brief Get the type ID.
1439 * \return The object TypeId.
1440 */
1441 static TypeId GetTypeId();
1442
1444 : m_length()
1445 {
1446 }
1447
1448 ~TestObject() override
1449 {
1450 }
1451
1452 private:
1453 Length m_length; //!< Length object
1454 };
1455
1456 private:
1457 /**
1458 * Test that a LengthValue can be constructed from a Length instance
1459 */
1461
1462 /**
1463 * Test that a LengthValue can be serialized to a string
1464 */
1466
1467 /**
1468 * Test that a LengthValue can be deserialized from a string
1469 */
1471
1472 /**
1473 * Test that a LengthValue works as an attribute
1474 */
1475 void TestObjectAttribute();
1476
1477 /**
1478 * Test that a StringValue is converted to LengthValue
1479 */
1481
1482 // Inherited function
1483 void DoRun() override;
1484};
1485
1486TypeId
1488{
1489 static TypeId tid = TypeId("LengthValueTestCase::TestObject")
1490 .SetParent<Object>()
1491 .SetGroupName("Test")
1492 .AddConstructor<TestObject>()
1493 .AddAttribute("Length",
1494 "Length value",
1495 LengthValue(),
1498
1499 return tid;
1500}
1501
1502void
1504{
1505 Length l = KiloMeters(2);
1506 LengthValue value(l);
1507
1508 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value");
1509}
1510
1511void
1513{
1515
1516 Length l = KiloMeters(2);
1517 LengthValue value(l);
1518
1519 std::string output = value.SerializeToString(checker);
1520
1521 NS_TEST_ASSERT_MSG_EQ(output, "2000 m", "Length attribute serialization has wrong output");
1522}
1523
1524void
1526{
1528
1529 Length l = KiloMeters(2);
1530 std::ostringstream stream;
1531 stream << l;
1532
1533 LengthValue value;
1534 bool result = value.DeserializeFromString(stream.str(), checker);
1535
1536 NS_TEST_ASSERT_MSG_EQ(result, true, "Length attribute deserialization failed");
1537 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value after deserialization");
1538}
1539
1540void
1542{
1543 Length expected(5, Unit::Kilometer);
1545
1546 obj->SetAttribute("Length", LengthValue(expected));
1547
1548 LengthValue val;
1549 obj->GetAttribute("Length", val);
1550
1551 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1552}
1553
1554void
1556{
1557 Length expected(5, Unit::Kilometer);
1559
1560 std::stringstream stream;
1561 stream << expected.As(Unit::Kilometer);
1562
1563 obj->SetAttribute("Length", StringValue(stream.str()));
1564
1565 LengthValue val;
1566 obj->GetAttribute("Length", val);
1567
1568 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1569}
1570
1571void
1580
1581/**
1582 * \ingroup length-tests
1583 * The Test Suite that runs the test case
1584 */
1586{
1587 public:
1588 /**
1589 * Default Constructor
1590 */
1592};
1593
1595 : TestSuite("length")
1596{
1597 AddTestCase(new LengthTestCase(), TestCase::Duration::QUICK);
1598 AddTestCase(new LengthValueTestCase(), TestCase::Duration::QUICK);
1599}
1600
1601/**
1602 * LengthTestSuite instance
1603 */
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:261
double Value() const
The value of the quantity.
Definition length.h:309
Represents a length in meters.
Definition length.h:233
double GetDouble() const
Current length value.
Definition length.cc:370
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
Definition length.cc:346
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition length.cc:307
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition length.cc:376
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:233
Unit
Units of length in various measurement systems that are supported by the Length class.
Definition length.h:240
bool IsLess(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is greater in value than this instance.
Definition length.cc:330
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition length.cc:322
Length Get() const
Definition length.cc:230
A base class which provides memory management and object aggregation.
Definition object.h:78
Smart pointer class similar to boost::intrusive_ptr.
Hold variables of type string.
Definition string.h:45
encapsulates test code
Definition test.h:1050
void AddTestCase(TestCase *testCase, Duration duration=Duration::QUICK)
Add an individual child TestCase to this test suite.
Definition test.cc:292
A suite of tests to run.
Definition test.h:1267
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:806
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:788
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:812
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:830
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:824
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition length.cc:490
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:782
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:836
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:800
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:794
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:471
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:776
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition length.cc:818
Ptr< T > CreateObject(Args &&... args)
Create an object by type, with varying number of constructor parameters.
Definition object.h:619
#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:134
#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:327
static LengthTestSuite gLengthTestSuite
LengthTestSuite instance.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeLengthChecker()
Definition length.cc:230
Ptr< const AttributeAccessor > MakeLengthAccessor(T1 a1)
Definition length.h:612
-ray-to-three-gpp-ch-calibration