A Discrete-Event Network Simulator
API
length-test-suite.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2019 Lawrence Livermore National Laboratory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Authors: Mathew Bielejeski<bielejeski1@llnl.gov>
19 */
20
21#include "ns3/length.h"
22#include "ns3/log.h"
23#include "ns3/object.h"
24#include "ns3/string.h"
25#include "ns3/test.h"
26
27#ifdef HAVE_BOOST
28#include <boost/units/base_units/us/foot.hpp>
29#include <boost/units/systems/si.hpp>
30#include <boost/units/systems/si/prefixes.hpp>
31#endif
32
33#include <array>
34#include <cmath>
35#include <functional>
36#include <initializer_list>
37#include <iomanip>
38#include <limits>
39#include <map>
40#include <sstream>
41#include <string>
42#include <tuple>
43
55using namespace ns3;
56
61
66{
67public:
72 : TestCase ("length-tests")
73 {}
74
78 virtual ~LengthTestCase () = default;
79
80protected:
87 void AssertFalse (bool condition, std::string msg)
88 {
89 NS_TEST_ASSERT_MSG_EQ (condition, false, msg);
90 }
91
98 void AssertTrue (bool condition, std::string msg)
99 {
100 NS_TEST_ASSERT_MSG_EQ (condition, true, msg);
101 }
102
103private:
108
113
119
125
131
137
145 void TestConstructLengthFromString (double unitValue,
146 double meterValue,
147 double tolerance,
148 const std::initializer_list<std::string>& symbols);
149
167#ifdef HAVE_BOOST_UNITS
172 void TestConstructLengthFromBoostUnits ();
173 void TestConstructLengthFromBoostUnitsMeters ();
174 void TestConstructLengthFromBoostUnitsKiloMeters ();
175 void TestConstructLengthFromBoostUnitsFeet ();
177#endif
178
190
195
196
201 void TestCopyAssignment ();
202
207 void TestMoveAssignment ();
208
213
226 void TestIsLessReturnsTrue ();
238
244
256 template<class T>
257 void TestLengthSerialization (const Length& l,
258 const T& unit,
259 const std::string& expectedOutput,
260 const std::string& context);
261
266
289 void TestAddingTwoLengths ();
315 void TestModReturnsZero ();
316 void TestModReturnsNonZero ();
319 virtual void DoRun ();
320};
321
322void
324{
325 Length l;
326
327 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), 0, "Default value of Length is not 0");
328}
329
330void
332{
333 const Length::Quantity VALUE (5.0, Unit::Meter);
334
335 Length l (VALUE);
336
337 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), VALUE.Value (),
338 "length constructed from meters has wrong value");
339}
340
341void
343{
344 using TestEntry = std::tuple<Length, std::string>;
345
346 const double expectedMeters = 1;
347 const std::initializer_list<TestEntry> inputs {
348 std::make_tuple (Length (1e9, Unit::Nanometer), "nanometer"),
349 std::make_tuple (Length (1e6, Unit::Micrometer), "micrometer"),
350 std::make_tuple (Length (1e3, Unit::Millimeter), "millimeter"),
351 std::make_tuple (Length (1e2, Unit::Centimeter), "centimeter"),
352 std::make_tuple (Length (1e-3, Unit::Kilometer), "kilometer"),
353 std::make_tuple (Length ( (1 / 1852.0), Unit::NauticalMile), "nautical_mile")
354 };
355
356 for (const TestEntry& entry : inputs )
357 {
358 const Length& l = std::get<0> (entry);
359 const std::string& context = std::get<1> (entry);
360
361 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), expectedMeters,
362 context << ": constructed length from SI unit has wrong value");
363 }
364}
365
366void
368{
369 using TestEntry = std::tuple<Length, std::string>;
370
371 const double expectedMeters = 0.3048;
372 const double tolerance = 0.0001;
373
374 const std::initializer_list<TestEntry> inputs {
375 std::make_tuple (Length (12.0, Unit::Inch), "inch"),
376 std::make_tuple (Length (1.0, Unit::Foot), "foot"),
377 std::make_tuple (Length ((1 / 3.0), Unit::Yard), "yard"),
378 std::make_tuple (Length ((1 / 5280.0), Unit::Mile), "mile"),
379 };
380
381 for (const TestEntry& entry : inputs )
382 {
383 const Length& l = std::get<0> (entry);
384 const std::string& context = std::get<1> (entry);
385
386 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedMeters, tolerance,
387 "constructed length from US unit (" << context << ") has wrong value");
388 }
389}
390
391void
393{
394 const double value = 5;
395 Length original (value, Unit::Meter);
396
397 Length copy (original);
398
399 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), original.GetDouble (),
400 "copy constructed length has wrong value");
401}
402
403void
405{
406 const double value = 5;
407 Length original (value, Unit::Meter);
408
409 Length copy (std::move (original));
410
411 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
412 "move constructed length has wrong value");
413}
414
415void
417 double meterValue,
418 double tolerance,
419 const std::initializer_list<std::string>& symbols)
420{
421 const std::array<std::string, 2> SEPARATORS {{"", " "}};
422
423 for (const std::string& symbol : symbols)
424 {
425 for ( const std::string& separator : SEPARATORS )
426 {
427 std::ostringstream stream;
428
429 stream << unitValue << separator << symbol;
430
431 Length l (stream.str ());
432
433 std::ostringstream msg;
434 msg << "string constructed length has wrong value: '" << stream.str () << "'";
435
436 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), meterValue, tolerance, msg.str ());
437 }
438 }
439}
440
441void
443{
444 const double value = 5;
445
446 TestConstructLengthFromString (value, value, 0,
447 {"m", "meter", "meters", "metre", "metres"});
448}
449
450void
452{
453 const double value = 5;
454 const double expectedValue = 5e-9;
455
456 TestConstructLengthFromString (value, expectedValue, 0,
457 {"nm", "nanometer", "nanometers",
458 "nanometre", "nanometres"});
459}
460
461void
463{
464 const double value = 5;
465 const double expectedValue = 5e-6;
466 const double tolerance = 1e-7;
467
468 TestConstructLengthFromString (value, expectedValue, tolerance,
469 {"um", "micrometer", "micrometers",
470 "micrometre", "micrometres"});
471}
472
473void
475{
476 const double value = 5;
477 const double expectedValue = 5e-3;
478 const double tolerance = 1e-4;
479
480 TestConstructLengthFromString (value, expectedValue, tolerance,
481 {"mm", "millimeter", "millimeters",
482 "millimetre", "millimetres"});
483}
484
485void
487{
488 const double value = 5;
489 const double expectedValue = 5e-2;
490 const double tolerance = 1e-3;
491
492 TestConstructLengthFromString (value, expectedValue, tolerance,
493 {"cm", "centimeter", "centimeters",
494 "centimetre", "centimetres"});
495}
496
497void
499{
500 const double value = 5;
501 const double expectedValue = 5e3;
502
503 TestConstructLengthFromString (value, expectedValue, 0,
504 {"km", "kilometer", "kilometers",
505 "kilometre", "kilometres"});
506}
507
508void
510{
511 const double value = 5;
512 const double expectedValue = 9260;
513
514 TestConstructLengthFromString (value, expectedValue, 0,
515 {"nmi", "nautical mile", "nautical miles"});
516}
517void
519{
520 const double value = 5;
521 const double expectedValue = 0.127;
522 const double tolerance = 1e-4;
523
524 TestConstructLengthFromString (value, expectedValue, tolerance,
525 {"in", "inch", "inches"});
526}
527
528void
530{
531 const double value = 5;
532 const double expectedValue = 1.524;
533 const double tolerance = 1e-4;
534
535 TestConstructLengthFromString (value, expectedValue, tolerance,
536 {"ft", "foot", "feet"});
537}
538
539void
541{
542 const double value = 5;
543 const double expectedValue = 4.572;
544 const double tolerance = 1e-4;
545
546 TestConstructLengthFromString (value, expectedValue, tolerance,
547 {"yd", "yard", "yards"});
548}
549
550void
552{
553 const double value = 5;
554 const double expectedValue = 8046.72;
555 const double tolerance = 1e-3;
556
557 TestConstructLengthFromString (value, expectedValue, tolerance,
558 {"mi", "mile", "miles"});
559}
560
561#ifdef HAVE_BOOST_UNITS
562void
563LengthTestCase::TestConstructLengthFromBoostUnits ()
564{
565 TestConstructLengthFromBoostUnitsMeters ();
566 TestConstructLengthFromBoostUnitsKiloMeters ();
567 TestConstructLengthFromBoostUnitsFeet ();
568}
569
570void
571LengthTestCase::TestConstructLengthFromBoostUnitsMeters ()
572{
573 namespace bu = boost::units;
574
575 auto meters = 5 * bu::si::meter;
576
577 Length l (meters);
578
579 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), meters.value (),
580 "Construction from boost::units meters produced "
581 "incorrect value");
582}
583
584void
585LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters ()
586{
587 namespace bu = boost::units;
588 auto kilometer = bu::si::kilo * bu::si::meter;
589
590 const double expectedValue = 5000;
591 auto quantity = 5 * kilometer;
592
593 Length l (quantity);
594
595 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), expectedValue,
596 "Construction from boost::units kilometers produced "
597 "incorrect value");
598}
599
600void
601LengthTestCase::TestConstructLengthFromBoostUnitsFeet ()
602{
603 namespace bu = boost::units;
604
605 bu::us::foot_base_unit::unit_type Foot;
606
607 const double expectedValue = 3.048;
608 auto feet = 10 * Foot;
609
610 Length l (feet);
611
612 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedValue, 0.001,
613 "Construction from boost::units foot produced "
614 "incorrect value");
615}
616#endif
617
618void
620{
621 using Builder = std::function<Length (double)>;
622
623 double inputValue = 10;
624
625 std::map<Unit, Builder> TESTDATA{
626 {Unit::Nanometer, NanoMeters},
627 {Unit::Micrometer, MicroMeters},
628 {Unit::Millimeter, MilliMeters},
629 {Unit::Centimeter, CentiMeters},
630 {Unit::Meter, Meters},
631 {Unit::Kilometer, KiloMeters},
632 {Unit::NauticalMile, NauticalMiles},
633 {Unit::Inch, Inches},
634 {Unit::Foot, Feet},
635 {Unit::Yard, Yards},
636 {Unit::Mile, Miles}
637 };
638
639 for (auto& entry : TESTDATA)
640 {
641 Length expected (inputValue, entry.first);
642
643 Length output = entry.second (inputValue);
644
645 NS_TEST_ASSERT_MSG_EQ (output, expected,
646 "The builder free function for " << entry.first <<
647 " did not create a Length with the correct value");
648 }
649}
650
651void
653{
654 bool result;
655 Length l;
656
657 std::tie (result, l) = Length::TryParse (1, "");
658
659 AssertFalse (result, "TryParse returned true on bad input");
660}
661
662void
664{
665 using TestInput = std::pair<double, std::string>;
666 using TestArgs = std::pair<double, double>;
667 std::map<TestInput, TestArgs> tests{
668 {{5, "m"}, {5, 0}},
669 {{5, " m"}, {5, 0}},
670 {{5, "kilometer"}, {5e3, 0}},
671 {{5, " kilometer"}, {5e3, 0}}
672 };
673
674 for (auto& entry : tests)
675 {
676 TestInput input = entry.first;
677 TestArgs args = entry.second;
678
679 bool result;
680 Length l;
681
682 std::tie (result, l) = Length::TryParse (input.first, input.second);
683
684 AssertTrue (result, "TryParse returned false when expecting true");
685
686 std::stringstream stream;
687 stream << "Parsing input (" << input.first << ", " << input.second
688 << ") returned the wrong value";
689
690 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), args.first, args.second, stream.str ());
691 }
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 (),
706 "copy assignment failed");
707}
708
709void
711{
712 const double value = 5;
713
714 Length original (value, Unit::Meter);
715
716 Length copy;
717 copy = std::move (original);
718
719 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
720 "move assignment failed");
721}
722
723void
725{
726 Length::Quantity input (5, Unit::Kilometer);
727
728 Length l;
729 Length expected (input);
730
731 l = input;
732
733 NS_TEST_ASSERT_MSG_EQ (l, expected,
734 "quantity assignment failed");
735}
736
737void
739{
740 const double value = 5;
741 Length one (value, Unit::Meter);
742 Length two (one);
743
744 AssertTrue (one.IsEqual (two), "IsEqual returned false for equal lengths");
745}
746
747void
749{
750 const double value = 5;
751 Length one (value, Unit::Meter);
752 Length two ( value, Unit::Foot );
753
754 AssertFalse (one.IsEqual (two), "IsEqual returned true for unequal lengths");
755}
756
757void
759{
760 const double value = 5;
761 const double tolerance = 0.1;
762
763 Length one (value, Unit::Meter);
764 Length two ( (value + 0.1), Unit::Meter);
765
766 AssertTrue (one.IsEqual (two, tolerance),
767 "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),
780 "IsEqual returned true for almost equal lengths");
781}
782
783void
785{
786 const double value = 5;
787
788 Length one (value, Unit::Meter);
789 Length two ( (value + 0.1), Unit::Meter);
790
791 AssertTrue (one.IsNotEqual (two),
792 "IsNotEqual returned false for not equal lengths");
793}
794
795void
797{
798 const double value = 5;
799
800 Length one (value, Unit::Meter);
801 Length two ( one );
802
803 AssertFalse (one.IsNotEqual (two),
804 "IsNotEqual returned true for equal lengths");
805}
806
807void
809{
810 const double tolerance = 0.001;
811
812 Length one ( 5.01, Unit::Meter);
813 Length two ( 5.02, Unit::Meter);
814
815 AssertTrue (one.IsNotEqual (two, tolerance),
816 "IsNotEqual with tolerance returned false for not equal lengths");
817}
818
819void
821{
822 const double tolerance = 0.01;
823
824 Length one ( 5.01, Unit::Meter);
825 Length two ( 5.02, Unit::Meter);
826
827 AssertFalse (one.IsNotEqual (two, tolerance),
828 "IsNotEqual with tolerance returned true for not equal lengths");
829}
830
831void
833{
834 const double value = 5;
835
836 Length one (value, Unit::Meter);
837 Length two ( (value + 0.1), Unit::Meter);
838
839 AssertTrue (one.IsLess (two),
840 "IsLess returned false for non equal lengths");
841}
842
843void
845{
846 const double value = 5;
847
848 Length one (value, Unit::Meter);
849 Length two ( one );
850
851 AssertFalse (one.IsLess (two),
852 "IsLess returned true for equal lengths");
853}
854
855void
857{
858 const double tolerance = 0.01;
859
860 Length one ( 5.1234, Unit::Meter );
861 Length two ( 5.1278, Unit::Meter );
862
863 AssertFalse (one.IsLess (two, tolerance),
864 "IsLess with tolerance returned true");
865}
866
867void
869{
870 Length one (2.0, Unit::Meter);
871 Length two (1.0, Unit::Meter);
872
873 AssertTrue (one.IsGreater (two),
874 "IsGreater returned false");
875}
876
877void
879{
880 Length one (2.0, Unit::Meter);
881 Length two (1.0, Unit::Meter);
882
883 AssertFalse (two.IsGreater (one),
884 "IsGreater returned true");
885}
886
887void
889{
890 const double tolerance = 0.01;
891
892 Length one (5.1234, Unit::Meter);
893 Length two (5.1278, Unit::Meter);
894
895 AssertFalse (two.IsGreater (one, tolerance),
896 "IsGreater returned true");
897}
898
899void
901{
902 Length l (1.0, Unit::Meter);
903
904 std::stringstream stream;
905
906 stream << l;
907
908 NS_TEST_ASSERT_MSG_EQ (stream.str (), "1 m",
909 "unexpected output from operator<<");
910}
911
912void
914{
915 const double value = 5;
916
917 Length l;
918
919 std::stringstream stream;
920
921 stream << value << "m";
922
923 stream >> l;
924
925 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), value,
926 "unexpected length from operator>>");
927}
928
929template<class T>
930void
932 const T& unit,
933 const std::string& expectedOutput,
934 const std::string& context)
935{
936 const std::string msg = context + ": unexpected output when serializing length";
937
938 std::ostringstream stream;
939
940 stream << std::fixed
941 << std::setprecision (5)
942 << l.As (unit);
943
944 NS_TEST_ASSERT_MSG_EQ (stream.str (), expectedOutput, msg);
945}
946
947void
949{
950 Length l (1.0, Unit::Meter);
951
952 TestLengthSerialization (l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
953 TestLengthSerialization (l, Unit::Micrometer, "1000000.00000 um", "micrometers");
954 TestLengthSerialization (l, Unit::Millimeter, "1000.00000 mm", "millimeters");
955 TestLengthSerialization (l, Unit::Centimeter, "100.00000 cm", "centimeters");
956 TestLengthSerialization (l, Unit::Meter, "1.00000 m", "meters");
957 TestLengthSerialization (l, Unit::Kilometer, "0.00100 km", "kilometers");
958 TestLengthSerialization (l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
959 TestLengthSerialization (l, Unit::Inch, "39.37008 in", "inches");
960 TestLengthSerialization (l, Unit::Foot, "3.28084 ft", "feet");
961 TestLengthSerialization (l, Unit::Yard, "1.09361 yd", "yards");
962 TestLengthSerialization (l, Unit::Mile, "0.00062 mi", "miles");
963}
964
965void
967{
968 const double value = 5;
969
970 Length one ( value, Unit::Meter );
971 Length two ( value, Unit::Meter );
972
973 AssertTrue ( one == two,
974 "operator== returned false for equal lengths");
975}
976
977void
979{
980 const double value = 5;
981
982 Length one ( value, Unit::Meter );
983 Length two ( value, Unit::Kilometer );
984
985 AssertFalse ( one == two,
986 "operator== returned true for non equal lengths");
987}
988
989void
991{
992 const double value = 5;
993
994 Length one ( value, Unit::Meter );
995 Length two ( value, Unit::Kilometer);
996
997 AssertTrue ( one != two,
998 "operator!= returned false for non equal lengths");
999
1000}
1001
1002void
1004{
1005 const double value = 5;
1006
1007 Length one ( value, Unit::Meter );
1008 Length two ( value, Unit::Meter );
1009
1010 AssertFalse ( one != two,
1011 "operator!= returned true for equal lengths");
1012
1013}
1014
1015void
1017{
1018 const double value = 5;
1019
1020 Length one ( value, Unit::Meter );
1021 Length two ( value, Unit::Kilometer);
1022
1023 AssertTrue ( one < two,
1024 "operator< returned false for smaller length");
1025}
1026
1027void
1029{
1030 const double value = 5;
1031
1032 Length one ( value, Unit::Meter );
1033 Length two ( value, Unit::Kilometer);
1034
1035 AssertFalse ( two < one,
1036 "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 Length three ( one );
1047
1048 AssertTrue ( one <= two,
1049 "operator<= returned false for smaller length");
1050
1051 AssertTrue ( one <= three,
1052 "operator<= returned false for equal lengths");
1053}
1054
1055void
1057{
1058 const double value = 5;
1059
1060 Length one ( value, Unit::Meter );
1061 Length two ( value, Unit::Kilometer);
1062
1063 AssertFalse ( two <= one,
1064 "operator<= returned true for larger length");
1065}
1066
1067void
1069{
1070 const double value = 5;
1071
1072 Length one ( value, Unit::Meter );
1073 Length two ( value, Unit::Kilometer);
1074
1075 AssertTrue ( two > one,
1076 "operator> returned false for larger length");
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,
1088 "operator> returned true for smaller length");
1089}
1090
1091void
1093{
1094 const double value = 5;
1095
1096 Length one ( value, Unit::Meter );
1097 Length two ( value, Unit::Kilometer);
1098 Length three ( one );
1099
1100 AssertTrue ( two >= one,
1101 "operator>= returned false for larger length");
1102
1103 AssertTrue ( one >= three,
1104 "operator>= returned false for equal lengths");
1105}
1106
1107void
1109{
1110 const double value = 5;
1111
1112 Length one ( value, Unit::Meter );
1113 Length two ( value, Unit::Kilometer);
1114
1115 AssertFalse ( one >= two,
1116 "operator>= returned true for smaller length");
1117}
1118
1119void
1121{
1122 const double value = 1;
1123 const double expectedOutput = 2;
1124
1125 Length one ( value, Unit::Meter );
1126 Length two ( value, Unit::Meter );
1127
1128 Length result = one + two;
1129
1130 NS_TEST_ASSERT_MSG_EQ ( one.GetDouble (), value,
1131 "operator+ modified first operand");
1132 NS_TEST_ASSERT_MSG_EQ ( two.GetDouble (), value,
1133 "operator+ modified second operand");
1134 NS_TEST_ASSERT_MSG_EQ ( result.GetDouble (), expectedOutput,
1135 "operator+ returned incorrect value");
1136}
1137
1138void
1140{
1141 const double value = 1;
1142 const double expectedOutput = 2;
1143
1144 Length one ( value, Unit::Meter );
1145
1146 Length result = one + Length::Quantity (value, Unit::Meter);
1147
1148 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1149 "operator+ modified first operand");
1150 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1151 "operator+ returned incorrect value");
1152}
1153
1154void
1156{
1157 const double value = 1;
1158 const double expectedOutput = 2;
1159
1160 Length one ( value, Unit::Meter );
1161
1162 Length result = Length::Quantity (value, Unit::Meter) + one;
1163
1164 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1165 "operator+ modified first operand");
1166 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1167 "operator+ returned incorrect value");
1168}
1169
1170void
1172{
1173 const double value = 1;
1174 const double expectedOutput = 0;
1175
1176 Length one ( value, Unit::Meter );
1177 Length two ( value, Unit::Meter );
1178
1179 Length result = one - two;
1180
1181 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1182 "operator- modified first operand");
1183 NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), value,
1184 "operator- modified second operand");
1185 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1186 "operator- returned incorrect value");
1187}
1188
1189void
1191{
1192 const double value = 1;
1193 const double expectedOutput = 0;
1194
1195 Length one ( value, Unit::Meter );
1196
1197 Length result = one - Length::Quantity ( value, Unit::Meter);
1198
1199 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1200 "operator- modified first operand");
1201 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1202 "operator- returned incorrect value");
1203}
1204
1205void
1207{
1208 const double value = 1;
1209 const double expectedOutput = 0;
1210
1211 Length one ( value, Unit::Meter );
1212
1213 Length result = Length::Quantity (value, Unit::Meter) - one;
1214
1215 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1216 "operator- modified second operand");
1217 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1218 "operator- returned incorrect value");
1219}
1220
1221void
1223{
1224 const double value = 1;
1225 const double scalar = 5;
1226 const double expectedOutput = value * scalar;
1227
1228 Length one ( value, Unit::Meter );
1229 Length result = one * scalar;
1230
1231 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1232 "operator* modified first operand");
1233 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1234 "operator* returned incorrect value");
1235}
1236
1237void
1239{
1240 const double value = 1;
1241 const double scalar = 5;
1242 const double expectedOutput = value * scalar;
1243
1244 Length one ( value, Unit::Meter );
1245 Length result = scalar * one;
1246
1247 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1248 "operator* modified second operand");
1249 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1250 "operator* returned incorrect value");
1251}
1252
1253void
1255{
1256 const double value = 10;
1257 const double scalar = 5;
1258 const double expectedOutput = value / scalar;
1259
1260 Length one ( value, Unit::Meter );
1261 Length result = one / scalar;
1262
1263 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1264 "operator/ modified first operand");
1265 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1266 "operator/ returned incorrect value");
1267}
1268
1269void
1271{
1272 const double valueOne = 100;
1273 const double valueTwo = 2;
1274 const double expectedOutput = valueOne / valueTwo;
1275
1276 Length one ( valueOne, Unit::Meter );
1277 Length two ( valueTwo, Unit::Meter );
1278
1279 double result = one / two;
1280
1281 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), valueOne,
1282 "operator/ modified first operand");
1283 NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), valueTwo,
1284 "operator/ modified second operand");
1285 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1286 "operator/ returned incorrect value");
1287
1288}
1289
1290void
1292{
1293 const double value = 1;
1294
1295 Length one ( value, Unit::Meter );
1296 Length two;
1297
1298 double result = one / two;
1299
1300 AssertTrue ( std::isnan (result),
1301 "operator/ did not return NaN when dividing by zero");
1302}
1303
1304void
1306{
1307 const double topValue = 100;
1308 const double bottomValue = 20;
1309 const int64_t expectedOutput = 5;
1310
1311 Length numerator (topValue, Unit::Meter);
1312 Length denominator (bottomValue, Unit::Meter);
1313
1314 auto result = Div (numerator, denominator);
1315
1316 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1317 "Div() returned an incorrect value");
1318}
1319
1320void
1322{
1323 const double topValue = 100;
1324 const double bottomValue = 20;
1325 const int64_t expectedOutput = 5;
1326 const int64_t expectedRemainder = 0;
1327
1328 Length numerator (topValue, Unit::Meter);
1329 Length denominator (bottomValue, Unit::Meter);
1330 Length remainder;
1331
1332 auto result = Div (numerator, denominator, &remainder);
1333
1334 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1335 "Div() returned an incorrect value");
1336 NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
1337 "Div() returned an incorrect remainder");
1338}
1339
1340void
1342{
1343 const double topValue = 110;
1344 const double bottomValue = 20;
1345 const int64_t expectedOutput = 5;
1346 const int64_t expectedRemainder = 10;
1347
1348 Length numerator (topValue, Unit::Meter);
1349 Length denominator (bottomValue, Unit::Meter);
1350 Length remainder;
1351
1352 auto result = Div (numerator, denominator, &remainder);
1353
1354 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1355 "Div() returned an incorrect value");
1356 NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
1357 "Div() returned an incorrect remainder");
1358}
1359
1360void
1362{
1363 Length numerator (10, Unit::Meter);
1364 Length denominator (2, Unit::Meter);
1365
1366 auto result = Mod (numerator, denominator);
1367
1368 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), 0,
1369 "Mod() returned a non zero value");
1370}
1371
1372void
1374{
1375 Length numerator (14, Unit::Meter);
1376 Length denominator (3, Unit::Meter);
1377 const double expectedValue = 2;
1378
1379 auto result = Mod (numerator, denominator);
1380
1381 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedValue,
1382 "Mod() returned the wrong value");
1383}
1384
1385void
1387{
1389
1391
1393
1395
1397
1399
1411
1412#ifdef HAVE_BOOST_UNITS
1413 TestConstructLengthFromBoostUnits ();
1414#endif
1415
1417
1420
1424
1439
1441
1443
1456
1468
1472
1475}
1476
1483{
1484public:
1489 : TestCase ("length-value-tests")
1490 {}
1491
1496 {}
1497
1498private:
1500 class TestObject : public Object
1501 {
1502 public:
1507 static TypeId GetTypeId ();
1508
1510 : m_length ()
1511 {}
1512
1513 virtual ~TestObject ()
1514 {}
1515
1516 private:
1518 };
1519
1520private:
1525
1530
1535
1539 void TestObjectAttribute ();
1540
1545
1546 // Inherited function
1547 virtual void DoRun ();
1548};
1549
1550TypeId
1552{
1553 static TypeId tid = TypeId ("LengthValueTestCase::TestObject")
1554 .SetParent<Object> ()
1555 .SetGroupName ("Test")
1556 .AddConstructor<TestObject> ()
1557 .AddAttribute ("Length",
1558 "Length value",
1559 LengthValue (),
1562 ;
1563
1564 return tid;
1565}
1566
1567void
1569{
1570 Length l = KiloMeters (2);
1571 LengthValue value (l);
1572
1573 NS_TEST_ASSERT_MSG_EQ (value.Get (), l, "Length attribute has wrong value");
1574}
1575
1576void
1578{
1580
1581 Length l = KiloMeters (2);
1582 LengthValue value (l);
1583
1584 std::string output = value.SerializeToString (checker);
1585
1586 NS_TEST_ASSERT_MSG_EQ (output, "2000 m",
1587 "Length attribute serialization has wrong output");
1588}
1589
1590void
1592{
1594
1595 Length l = KiloMeters (2);
1596 std::ostringstream stream;
1597 stream << l;
1598
1599 LengthValue value;
1600 bool result = value.DeserializeFromString (stream.str (), checker);
1601
1603 "Length attribute deserialization failed");
1604 NS_TEST_ASSERT_MSG_EQ (value.Get (), l,
1605 "Length attribute has wrong value after deserialization");
1606}
1607
1608void
1610{
1611 Length expected (5, Unit::Kilometer);
1612 Ptr<TestObject> obj = CreateObject<TestObject> ();
1613
1614 obj->SetAttribute ("Length", LengthValue (expected));
1615
1616 LengthValue val;
1617 obj->GetAttribute ("Length", val);
1618
1619 NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
1620 "Length attribute does not have expected value");
1621}
1622
1623void
1625{
1626 Length expected (5, Unit::Kilometer);
1627 Ptr<TestObject> obj = CreateObject<TestObject> ();
1628
1629 std::stringstream stream;
1630 stream << expected.As (Unit::Kilometer);
1631
1632 obj->SetAttribute ("Length", StringValue (stream.str()));
1633
1634 LengthValue val;
1635 obj->GetAttribute ("Length", val);
1636
1637 NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
1638 "Length attribute does not have expected value");
1639}
1640
1641void
1643{
1649}
1650
1656{
1657public:
1661 LengthTestSuite ();
1662};
1663
1665 : TestSuite ("length")
1666{
1667 AddTestCase ( new LengthTestCase (), TestCase::QUICK );
1668 AddTestCase ( new LengthValueTestCase (), TestCase::QUICK );
1669}
1670
1675
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.
virtual void DoRun()
Implementation to actually run this TestCase.
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.
virtual ~LengthTestCase()=default
Destructor.
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 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.
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.
virtual ~LengthValueTestCase()
Destructor.
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.
virtual void DoRun()
Implementation to actually run this TestCase.
void TestSetAttributeUsingStringValue()
Test that a StringValue is converted to LengthValue.
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:319
Represents a length in meters.
Definition: length.h:244
double GetDouble() const
Current length value.
Definition: length.cc:382
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
Definition: length.cc:358
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition: length.cc:319
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:388
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:342
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:334
AttributeValue implementation for Length.
Definition: length.h:623
virtual std::string SerializeToString(Ptr< const AttributeChecker > checker) const
Length Get(void) const
virtual bool DeserializeFromString(std::string value, Ptr< const AttributeChecker > checker)
A base class which provides memory management and object aggregation.
Definition: object.h:88
Smart pointer class similar to boost::intrusive_ptr.
Definition: ptr.h:74
Hold variables of type string.
Definition: string.h:41
encapsulates test code
Definition: test.h:994
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
Definition: test.cc:299
A suite of tests to run.
Definition: test.h:1188
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:922
Ptr< const AttributeChecker > MakeLengthChecker(void)
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:821
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:803
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:827
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:845
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:839
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:502
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:797
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:851
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:815
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:809
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:483
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:791
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:833
#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:141
#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:323
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.