A Discrete-Event Network Simulator
API
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
53using namespace ns3;
54
59
64{
65 public:
70 : TestCase("length-tests")
71 {
72 }
73
77 ~LengthTestCase() override = default;
78
79 protected:
86 void AssertFalse(bool condition, std::string msg)
87 {
88 NS_TEST_ASSERT_MSG_EQ(condition, false, msg);
89 }
90
97 void AssertTrue(bool condition, std::string msg)
98 {
99 NS_TEST_ASSERT_MSG_EQ(condition, true, msg);
100 }
101
102 private:
107
112
118
124
130
136
144 void TestConstructLengthFromString(double unitValue,
145 double meterValue,
146 double tolerance,
147 const std::initializer_list<std::string>& symbols);
148
166#ifdef HAVE_BOOST_UNITS
171 void TestConstructLengthFromBoostUnits();
172 void TestConstructLengthFromBoostUnitsMeters();
173 void TestConstructLengthFromBoostUnitsKiloMeters();
174 void TestConstructLengthFromBoostUnitsFeet();
176#endif
177
189
194
199 void TestCopyAssignment();
200
205 void TestMoveAssignment();
206
211
236
242
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
264
313 void TestModReturnsZero();
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{{Unit::Nanometer, NanoMeters},
635 {Unit::Micrometer, MicroMeters},
636 {Unit::Millimeter, MilliMeters},
637 {Unit::Centimeter, CentiMeters},
638 {Unit::Meter, Meters},
639 {Unit::Kilometer, KiloMeters},
640 {Unit::NauticalMile, NauticalMiles},
641 {Unit::Inch, Inches},
642 {Unit::Foot, Feet},
643 {Unit::Yard, Yards},
644 {Unit::Mile, Miles}};
645
646 for (auto& entry : TESTDATA)
647 {
648 Length expected(inputValue, entry.first);
649
650 Length output = entry.second(inputValue);
651
653 expected,
654 "The builder free function for "
655 << entry.first
656 << " did not create a Length with the correct value");
657 }
658}
659
660void
662{
663 auto l = Length::TryParse(1, "");
664
665 AssertFalse(l.has_value(), "TryParse returned true on bad input");
666}
667
668void
670{
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}},
674 {{5, " m"}, {5, 0}},
675 {{5, "kilometer"}, {5e3, 0}},
676 {{5, " kilometer"}, {5e3, 0}}};
677
678 for (auto& entry : tests)
679 {
680 TestInput input = entry.first;
681 TestArgs args = entry.second;
682
683 auto l = Length::TryParse(input.first, input.second);
684
685 AssertTrue(l.has_value(), "TryParse returned false when expecting true");
686
687 std::stringstream stream;
688 stream << "Parsing input (" << input.first << ", " << input.second
689 << ") returned the wrong value";
690
691 NS_TEST_ASSERT_MSG_EQ_TOL(l->GetDouble(), args.first, args.second, stream.str());
692 }
693}
694
695void
697{
698 const double value = 5;
699
700 Length original(value, Unit::Meter);
701
702 Length copy;
703 copy = original;
704
705 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), original.GetDouble(), "copy assignment failed");
706}
707
708void
710{
711 const double value = 5;
712
713 Length original(value, Unit::Meter);
714
715 Length copy;
716 copy = std::move(original);
717
718 NS_TEST_ASSERT_MSG_EQ(copy.GetDouble(), value, "move assignment failed");
719}
720
721void
723{
724 Length::Quantity input(5, Unit::Kilometer);
725
726 Length l;
727 Length expected(input);
728
729 l = input;
730
731 NS_TEST_ASSERT_MSG_EQ(l, expected, "quantity assignment failed");
732}
733
734void
736{
737 const double value = 5;
738 Length one(value, Unit::Meter);
739 Length two(one);
740
741 AssertTrue(one.IsEqual(two), "IsEqual returned false for equal lengths");
742}
743
744void
746{
747 const double value = 5;
748 Length one(value, Unit::Meter);
749 Length two(value, Unit::Foot);
750
751 AssertFalse(one.IsEqual(two), "IsEqual returned true for unequal lengths");
752}
753
754void
756{
757 const double value = 5;
758 const double tolerance = 0.1;
759
760 Length one(value, Unit::Meter);
761 Length two((value + 0.1), Unit::Meter);
762
763 AssertTrue(one.IsEqual(two, tolerance), "IsEqual returned false for almost equal lengths");
764}
765
766void
768{
769 const double value = 5;
770 const double tolerance = 0.01;
771
772 Length one(value, Unit::Meter);
773 Length two((value + 0.1), Unit::Meter);
774
775 AssertFalse(one.IsEqual(two, tolerance), "IsEqual returned true for almost equal lengths");
776}
777
778void
780{
781 const double value = 5;
782
783 Length one(value, Unit::Meter);
784 Length two((value + 0.1), Unit::Meter);
785
786 AssertTrue(one.IsNotEqual(two), "IsNotEqual returned false for not equal lengths");
787}
788
789void
791{
792 const double value = 5;
793
794 Length one(value, Unit::Meter);
795 Length two(one);
796
797 AssertFalse(one.IsNotEqual(two), "IsNotEqual returned true for equal lengths");
798}
799
800void
802{
803 const double tolerance = 0.001;
804
805 Length one(5.01, Unit::Meter);
806 Length two(5.02, Unit::Meter);
807
808 AssertTrue(one.IsNotEqual(two, tolerance),
809 "IsNotEqual with tolerance returned false for not equal lengths");
810}
811
812void
814{
815 const double tolerance = 0.01;
816
817 Length one(5.01, Unit::Meter);
818 Length two(5.02, Unit::Meter);
819
820 AssertFalse(one.IsNotEqual(two, tolerance),
821 "IsNotEqual with tolerance returned true for not equal lengths");
822}
823
824void
826{
827 const double value = 5;
828
829 Length one(value, Unit::Meter);
830 Length two((value + 0.1), Unit::Meter);
831
832 AssertTrue(one.IsLess(two), "IsLess returned false for non equal lengths");
833}
834
835void
837{
838 const double value = 5;
839
840 Length one(value, Unit::Meter);
841 Length two(one);
842
843 AssertFalse(one.IsLess(two), "IsLess returned true for equal lengths");
844}
845
846void
848{
849 const double tolerance = 0.01;
850
851 Length one(5.1234, Unit::Meter);
852 Length two(5.1278, Unit::Meter);
853
854 AssertFalse(one.IsLess(two, tolerance), "IsLess with tolerance returned true");
855}
856
857void
859{
860 Length one(2.0, Unit::Meter);
861 Length two(1.0, Unit::Meter);
862
863 AssertTrue(one.IsGreater(two), "IsGreater returned false");
864}
865
866void
868{
869 Length one(2.0, Unit::Meter);
870 Length two(1.0, Unit::Meter);
871
872 AssertFalse(two.IsGreater(one), "IsGreater returned true");
873}
874
875void
877{
878 const double tolerance = 0.01;
879
880 Length one(5.1234, Unit::Meter);
881 Length two(5.1278, Unit::Meter);
882
883 AssertFalse(two.IsGreater(one, tolerance), "IsGreater returned true");
884}
885
886void
888{
889 Length l(1.0, Unit::Meter);
890
891 std::stringstream stream;
892
893 stream << l;
894
895 NS_TEST_ASSERT_MSG_EQ(stream.str(), "1 m", "unexpected output from operator<<");
896}
897
898void
900{
901 const double value = 5;
902
903 Length l;
904
905 std::stringstream stream;
906
907 stream << value << "m";
908
909 stream >> l;
910
911 NS_TEST_ASSERT_MSG_EQ(l.GetDouble(), value, "unexpected length from operator>>");
912}
913
914template <class T>
915void
917 const T& unit,
918 const std::string& expectedOutput,
919 const std::string& context)
920{
921 const std::string msg = context + ": unexpected output when serializing length";
922
923 std::ostringstream stream;
924
925 stream << std::fixed << std::setprecision(5) << l.As(unit);
926
927 NS_TEST_ASSERT_MSG_EQ(stream.str(), expectedOutput, msg);
928}
929
930void
932{
933 Length l(1.0, Unit::Meter);
934
935 TestLengthSerialization(l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
936 TestLengthSerialization(l, Unit::Micrometer, "1000000.00000 um", "micrometers");
937 TestLengthSerialization(l, Unit::Millimeter, "1000.00000 mm", "millimeters");
938 TestLengthSerialization(l, Unit::Centimeter, "100.00000 cm", "centimeters");
939 TestLengthSerialization(l, Unit::Meter, "1.00000 m", "meters");
940 TestLengthSerialization(l, Unit::Kilometer, "0.00100 km", "kilometers");
941 TestLengthSerialization(l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
942 TestLengthSerialization(l, Unit::Inch, "39.37008 in", "inches");
943 TestLengthSerialization(l, Unit::Foot, "3.28084 ft", "feet");
944 TestLengthSerialization(l, Unit::Yard, "1.09361 yd", "yards");
945 TestLengthSerialization(l, Unit::Mile, "0.00062 mi", "miles");
946}
947
948void
950{
951 const double value = 5;
952
953 Length one(value, Unit::Meter);
954 Length two(value, Unit::Meter);
955
956 AssertTrue(one == two, "operator== returned false for equal lengths");
957}
958
959void
961{
962 const double value = 5;
963
964 Length one(value, Unit::Meter);
965 Length two(value, Unit::Kilometer);
966
967 AssertFalse(one == two, "operator== returned true for non equal lengths");
968}
969
970void
972{
973 const double value = 5;
974
975 Length one(value, Unit::Meter);
976 Length two(value, Unit::Kilometer);
977
978 AssertTrue(one != two, "operator!= returned false for non equal lengths");
979}
980
981void
983{
984 const double value = 5;
985
986 Length one(value, Unit::Meter);
987 Length two(value, Unit::Meter);
988
989 AssertFalse(one != two, "operator!= returned true for equal lengths");
990}
991
992void
994{
995 const double value = 5;
996
997 Length one(value, Unit::Meter);
998 Length two(value, Unit::Kilometer);
999
1000 AssertTrue(one < two, "operator< returned false for smaller length");
1001}
1002
1003void
1005{
1006 const double value = 5;
1007
1008 Length one(value, Unit::Meter);
1009 Length two(value, Unit::Kilometer);
1010
1011 AssertFalse(two < one, "operator< returned true for larger length");
1012}
1013
1014void
1016{
1017 const double value = 5;
1018
1019 Length one(value, Unit::Meter);
1020 Length two(value, Unit::Kilometer);
1021 Length three(one);
1022
1023 AssertTrue(one <= two, "operator<= returned false for smaller length");
1024
1025 AssertTrue(one <= three, "operator<= returned false for equal lengths");
1026}
1027
1028void
1030{
1031 const double value = 5;
1032
1033 Length one(value, Unit::Meter);
1034 Length two(value, Unit::Kilometer);
1035
1036 AssertFalse(two <= one, "operator<= returned true for larger length");
1037}
1038
1039void
1041{
1042 const double value = 5;
1043
1044 Length one(value, Unit::Meter);
1045 Length two(value, Unit::Kilometer);
1046
1047 AssertTrue(two > one, "operator> returned false for larger length");
1048}
1049
1050void
1052{
1053 const double value = 5;
1054
1055 Length one(value, Unit::Meter);
1056 Length two(value, Unit::Kilometer);
1057
1058 AssertFalse(one > two, "operator> returned true for smaller length");
1059}
1060
1061void
1063{
1064 const double value = 5;
1065
1066 Length one(value, Unit::Meter);
1067 Length two(value, Unit::Kilometer);
1068 Length three(one);
1069
1070 AssertTrue(two >= one, "operator>= returned false for larger length");
1071
1072 AssertTrue(one >= three, "operator>= returned false for equal lengths");
1073}
1074
1075void
1077{
1078 const double value = 5;
1079
1080 Length one(value, Unit::Meter);
1081 Length two(value, Unit::Kilometer);
1082
1083 AssertFalse(one >= two, "operator>= returned true for smaller length");
1084}
1085
1086void
1088{
1089 const double value = 1;
1090 const double expectedOutput = 2;
1091
1092 Length one(value, Unit::Meter);
1093 Length two(value, Unit::Meter);
1094
1095 Length result = one + two;
1096
1097 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1098 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator+ modified second operand");
1099 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1100}
1101
1102void
1104{
1105 const double value = 1;
1106 const double expectedOutput = 2;
1107
1108 Length one(value, Unit::Meter);
1109
1110 Length result = one + Length::Quantity(value, Unit::Meter);
1111
1112 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1113 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1114}
1115
1116void
1118{
1119 const double value = 1;
1120 const double expectedOutput = 2;
1121
1122 Length one(value, Unit::Meter);
1123
1124 Length result = Length::Quantity(value, Unit::Meter) + one;
1125
1126 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator+ modified first operand");
1127 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator+ returned incorrect value");
1128}
1129
1130void
1132{
1133 const double value = 1;
1134 const double expectedOutput = 0;
1135
1136 Length one(value, Unit::Meter);
1137 Length two(value, Unit::Meter);
1138
1139 Length result = one - two;
1140
1141 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1142 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), value, "operator- modified second operand");
1143 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1144}
1145
1146void
1148{
1149 const double value = 1;
1150 const double expectedOutput = 0;
1151
1152 Length one(value, Unit::Meter);
1153
1154 Length result = one - Length::Quantity(value, Unit::Meter);
1155
1156 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified first operand");
1157 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1158}
1159
1160void
1162{
1163 const double value = 1;
1164 const double expectedOutput = 0;
1165
1166 Length one(value, Unit::Meter);
1167
1168 Length result = Length::Quantity(value, Unit::Meter) - one;
1169
1170 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator- modified second operand");
1171 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator- returned incorrect value");
1172}
1173
1174void
1176{
1177 const double value = 1;
1178 const double scalar = 5;
1179 const double expectedOutput = value * scalar;
1180
1181 Length one(value, Unit::Meter);
1182 Length result = one * scalar;
1183
1184 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified first operand");
1185 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1186}
1187
1188void
1190{
1191 const double value = 1;
1192 const double scalar = 5;
1193 const double expectedOutput = value * scalar;
1194
1195 Length one(value, Unit::Meter);
1196 Length result = scalar * one;
1197
1198 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator* modified second operand");
1199 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator* returned incorrect value");
1200}
1201
1202void
1204{
1205 const double value = 10;
1206 const double scalar = 5;
1207 const double expectedOutput = value / scalar;
1208
1209 Length one(value, Unit::Meter);
1210 Length result = one / scalar;
1211
1212 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), value, "operator/ modified first operand");
1213 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedOutput, "operator/ returned incorrect value");
1214}
1215
1216void
1218{
1219 const double valueOne = 100;
1220 const double valueTwo = 2;
1221 const double expectedOutput = valueOne / valueTwo;
1222
1223 Length one(valueOne, Unit::Meter);
1224 Length two(valueTwo, Unit::Meter);
1225
1226 double result = one / two;
1227
1228 NS_TEST_ASSERT_MSG_EQ(one.GetDouble(), valueOne, "operator/ modified first operand");
1229 NS_TEST_ASSERT_MSG_EQ(two.GetDouble(), valueTwo, "operator/ modified second operand");
1230 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "operator/ returned incorrect value");
1231}
1232
1233void
1235{
1236 const double value = 1;
1237
1238 Length one(value, Unit::Meter);
1239 Length two;
1240
1241 double result = one / two;
1242
1243 AssertTrue(std::isnan(result), "operator/ did not return NaN when dividing by zero");
1244}
1245
1246void
1248{
1249 const double topValue = 100;
1250 const double bottomValue = 20;
1251 const int64_t expectedOutput = 5;
1252
1253 Length numerator(topValue, Unit::Meter);
1254 Length denominator(bottomValue, Unit::Meter);
1255
1256 auto result = Div(numerator, denominator);
1257
1258 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1259}
1260
1261void
1263{
1264 const double topValue = 100;
1265 const double bottomValue = 20;
1266 const int64_t expectedOutput = 5;
1267 const int64_t expectedRemainder = 0;
1268
1269 Length numerator(topValue, Unit::Meter);
1270 Length denominator(bottomValue, Unit::Meter);
1271 Length remainder;
1272
1273 auto result = Div(numerator, denominator, &remainder);
1274
1275 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1276 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1277 expectedRemainder,
1278 "Div() returned an incorrect remainder");
1279}
1280
1281void
1283{
1284 const double topValue = 110;
1285 const double bottomValue = 20;
1286 const int64_t expectedOutput = 5;
1287 const int64_t expectedRemainder = 10;
1288
1289 Length numerator(topValue, Unit::Meter);
1290 Length denominator(bottomValue, Unit::Meter);
1291 Length remainder;
1292
1293 auto result = Div(numerator, denominator, &remainder);
1294
1295 NS_TEST_ASSERT_MSG_EQ(result, expectedOutput, "Div() returned an incorrect value");
1296 NS_TEST_ASSERT_MSG_EQ(remainder.GetDouble(),
1297 expectedRemainder,
1298 "Div() returned an incorrect remainder");
1299}
1300
1301void
1303{
1304 Length numerator(10, Unit::Meter);
1305 Length denominator(2, Unit::Meter);
1306
1307 auto result = Mod(numerator, denominator);
1308
1309 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), 0, "Mod() returned a non zero value");
1310}
1311
1312void
1314{
1315 Length numerator(14, Unit::Meter);
1316 Length denominator(3, Unit::Meter);
1317 const double expectedValue = 2;
1318
1319 auto result = Mod(numerator, denominator);
1320
1321 NS_TEST_ASSERT_MSG_EQ(result.GetDouble(), expectedValue, "Mod() returned the wrong value");
1322}
1323
1324void
1326{
1328
1330
1332
1334
1336
1338
1350
1351#ifdef HAVE_BOOST_UNITS
1352 TestConstructLengthFromBoostUnits();
1353#endif
1354
1356
1359
1363
1378
1380
1382
1395
1407
1411
1414}
1415
1422{
1423 public:
1428 : TestCase("length-value-tests")
1429 {
1430 }
1431
1436 {
1437 }
1438
1439 private:
1441 class TestObject : public Object
1442 {
1443 public:
1448 static TypeId GetTypeId();
1449
1451 : m_length()
1452 {
1453 }
1454
1455 ~TestObject() override
1456 {
1457 }
1458
1459 private:
1461 };
1462
1463 private:
1468
1473
1478
1482 void TestObjectAttribute();
1483
1488
1489 // Inherited function
1490 void DoRun() override;
1491};
1492
1493TypeId
1495{
1496 static TypeId tid = TypeId("LengthValueTestCase::TestObject")
1497 .SetParent<Object>()
1498 .SetGroupName("Test")
1499 .AddConstructor<TestObject>()
1500 .AddAttribute("Length",
1501 "Length value",
1502 LengthValue(),
1505
1506 return tid;
1507}
1508
1509void
1511{
1512 Length l = KiloMeters(2);
1513 LengthValue value(l);
1514
1515 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value");
1516}
1517
1518void
1520{
1522
1523 Length l = KiloMeters(2);
1524 LengthValue value(l);
1525
1526 std::string output = value.SerializeToString(checker);
1527
1528 NS_TEST_ASSERT_MSG_EQ(output, "2000 m", "Length attribute serialization has wrong output");
1529}
1530
1531void
1533{
1535
1536 Length l = KiloMeters(2);
1537 std::ostringstream stream;
1538 stream << l;
1539
1541 bool result = value.DeserializeFromString(stream.str(), checker);
1542
1543 NS_TEST_ASSERT_MSG_EQ(result, true, "Length attribute deserialization failed");
1544 NS_TEST_ASSERT_MSG_EQ(value.Get(), l, "Length attribute has wrong value after deserialization");
1545}
1546
1547void
1549{
1550 Length expected(5, Unit::Kilometer);
1551 Ptr<TestObject> obj = CreateObject<TestObject>();
1552
1553 obj->SetAttribute("Length", LengthValue(expected));
1554
1555 LengthValue val;
1556 obj->GetAttribute("Length", val);
1557
1558 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1559}
1560
1561void
1563{
1564 Length expected(5, Unit::Kilometer);
1565 Ptr<TestObject> obj = CreateObject<TestObject>();
1566
1567 std::stringstream stream;
1568 stream << expected.As(Unit::Kilometer);
1569
1570 obj->SetAttribute("Length", StringValue(stream.str()));
1571
1572 LengthValue val;
1573 obj->GetAttribute("Length", val);
1574
1575 NS_TEST_ASSERT_MSG_EQ(val.Get(), expected, "Length attribute does not have expected value");
1576}
1577
1578void
1580{
1586}
1587
1593{
1594 public:
1599};
1600
1602 : TestSuite("length")
1603{
1604 AddTestCase(new LengthTestCase(), TestCase::QUICK);
1605 AddTestCase(new LengthValueTestCase(), TestCase::QUICK);
1606}
1607
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:380
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
Definition: length.cc:356
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition: length.cc:317
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:386
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:340
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:332
AttributeValue implementation for Length.
Definition: length.h:623
Length Get() const
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:78
Hold variables of type string.
Definition: string.h:42
encapsulates test code
Definition: test.h:1060
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:305
A suite of tests to run.
Definition: test.h:1256
a unique identifier for an interface.
Definition: type-id.h:60
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:935
Ptr< const AttributeChecker > MakeLengthChecker()
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:811
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:793
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:817
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:835
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:829
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:500
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:787
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:841
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:805
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:799
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:481
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:781
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:823
#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:144
#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:337
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.
value
Definition: second.py:41