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
54using namespace ns3;
55
60
65{
66public:
71 : TestCase ("length-tests")
72 {}
73
77 virtual ~LengthTestCase () = default;
78
79protected:
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
102private:
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
195
200 void TestCopyAssignment ();
201
206 void TestMoveAssignment ();
207
212
225 void TestIsLessReturnsTrue ();
237
243
255 template<class T>
256 void TestLengthSerialization (const Length& l,
257 const T& unit,
258 const std::string& expectedOutput,
259 const std::string& context);
260
265
288 void TestAddingTwoLengths ();
314 void TestModReturnsZero ();
315 void TestModReturnsNonZero ();
318 virtual void DoRun ();
319};
320
321void
323{
324 Length l;
325
326 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), 0, "Default value of Length is not 0");
327}
328
329void
331{
332 const Length::Quantity VALUE (5.0, Unit::Meter);
333
334 Length l (VALUE);
335
336 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), 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
355 for (const TestEntry& entry : inputs )
356 {
357 const Length& l = std::get<0> (entry);
358 const std::string& context = std::get<1> (entry);
359
360 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), 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
385 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedMeters, tolerance,
386 "constructed length from US unit (" << context << ") has wrong value");
387 }
388}
389
390void
392{
393 const double value = 5;
394 Length original (value, Unit::Meter);
395
396 Length copy (original);
397
398 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), original.GetDouble (),
399 "copy constructed length has wrong value");
400}
401
402void
404{
405 const double value = 5;
406 Length original (value, Unit::Meter);
407
408 Length copy (std::move (original));
409
410 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
411 "move constructed length has wrong value");
412}
413
414void
416 double meterValue,
417 double tolerance,
418 const std::initializer_list<std::string>& symbols)
419{
420 const std::array<std::string, 2> SEPARATORS {{"", " "}};
421
422 for (const std::string& symbol : symbols)
423 {
424 for ( const std::string& separator : SEPARATORS )
425 {
426 std::ostringstream stream;
427
428 stream << unitValue << separator << symbol;
429
430 Length l (stream.str ());
431
432 std::ostringstream msg;
433 msg << "string constructed length has wrong value: '" << stream.str () << "'";
434
435 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), meterValue, tolerance, msg.str ());
436 }
437 }
438}
439
440void
442{
443 const double value = 5;
444
445 TestConstructLengthFromString (value, value, 0,
446 {"m", "meter", "meters", "metre", "metres"});
447}
448
449void
451{
452 const double value = 5;
453 const double expectedValue = 5e-9;
454
455 TestConstructLengthFromString (value, expectedValue, 0,
456 {"nm", "nanometer", "nanometers",
457 "nanometre", "nanometres"});
458}
459
460void
462{
463 const double value = 5;
464 const double expectedValue = 5e-6;
465 const double tolerance = 1e-7;
466
467 TestConstructLengthFromString (value, expectedValue, tolerance,
468 {"um", "micrometer", "micrometers",
469 "micrometre", "micrometres"});
470}
471
472void
474{
475 const double value = 5;
476 const double expectedValue = 5e-3;
477 const double tolerance = 1e-4;
478
479 TestConstructLengthFromString (value, expectedValue, tolerance,
480 {"mm", "millimeter", "millimeters",
481 "millimetre", "millimetres"});
482}
483
484void
486{
487 const double value = 5;
488 const double expectedValue = 5e-2;
489 const double tolerance = 1e-3;
490
491 TestConstructLengthFromString (value, expectedValue, tolerance,
492 {"cm", "centimeter", "centimeters",
493 "centimetre", "centimetres"});
494}
495
496void
498{
499 const double value = 5;
500 const double expectedValue = 5e3;
501
502 TestConstructLengthFromString (value, expectedValue, 0,
503 {"km", "kilometer", "kilometers",
504 "kilometre", "kilometres"});
505}
506
507void
509{
510 const double value = 5;
511 const double expectedValue = 9260;
512
513 TestConstructLengthFromString (value, expectedValue, 0,
514 {"nmi", "nautical mile", "nautical miles"});
515}
516void
518{
519 const double value = 5;
520 const double expectedValue = 0.127;
521 const double tolerance = 1e-4;
522
523 TestConstructLengthFromString (value, expectedValue, tolerance,
524 {"in", "inch", "inches"});
525}
526
527void
529{
530 const double value = 5;
531 const double expectedValue = 1.524;
532 const double tolerance = 1e-4;
533
534 TestConstructLengthFromString (value, expectedValue, tolerance,
535 {"ft", "foot", "feet"});
536}
537
538void
540{
541 const double value = 5;
542 const double expectedValue = 4.572;
543 const double tolerance = 1e-4;
544
545 TestConstructLengthFromString (value, expectedValue, tolerance,
546 {"yd", "yard", "yards"});
547}
548
549void
551{
552 const double value = 5;
553 const double expectedValue = 8046.72;
554 const double tolerance = 1e-3;
555
556 TestConstructLengthFromString (value, expectedValue, tolerance,
557 {"mi", "mile", "miles"});
558}
559
560#ifdef HAVE_BOOST_UNITS
561void
562LengthTestCase::TestConstructLengthFromBoostUnits ()
563{
564 TestConstructLengthFromBoostUnitsMeters ();
565 TestConstructLengthFromBoostUnitsKiloMeters ();
566 TestConstructLengthFromBoostUnitsFeet ();
567}
568
569void
570LengthTestCase::TestConstructLengthFromBoostUnitsMeters ()
571{
572 namespace bu = boost::units;
573
574 auto meters = 5 * bu::si::meter;
575
576 Length l (meters);
577
578 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), meters.value (),
579 "Construction from boost::units meters produced "
580 "incorrect value");
581}
582
583void
584LengthTestCase::TestConstructLengthFromBoostUnitsKiloMeters ()
585{
586 namespace bu = boost::units;
587 auto kilometer = bu::si::kilo * bu::si::meter;
588
589 const double expectedValue = 5000;
590 auto quantity = 5 * kilometer;
591
592 Length l (quantity);
593
594 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), expectedValue,
595 "Construction from boost::units kilometers produced "
596 "incorrect value");
597}
598
599void
600LengthTestCase::TestConstructLengthFromBoostUnitsFeet ()
601{
602 namespace bu = boost::units;
603
604 bu::us::foot_base_unit::unit_type Foot;
605
606 const double expectedValue = 3.048;
607 auto feet = 10 * Foot;
608
609 Length l (feet);
610
611 NS_TEST_ASSERT_MSG_EQ_TOL (l.GetDouble (), expectedValue, 0.001,
612 "Construction from boost::units foot produced "
613 "incorrect value");
614}
615#endif
616
617void
619{
620 using Builder = std::function<Length (double)>;
621
622 double inputValue = 10;
623
624 std::map<Unit, Builder> TESTDATA{
625 {Unit::Nanometer, NanoMeters},
626 {Unit::Micrometer, MicroMeters},
627 {Unit::Millimeter, MilliMeters},
628 {Unit::Centimeter, CentiMeters},
629 {Unit::Meter, Meters},
630 {Unit::Kilometer, KiloMeters},
631 {Unit::NauticalMile, NauticalMiles},
632 {Unit::Inch, Inches},
633 {Unit::Foot, Feet},
634 {Unit::Yard, Yards},
635 {Unit::Mile, Miles}
636 };
637
638 for (auto& entry : TESTDATA)
639 {
640 Length expected (inputValue, entry.first);
641
642 Length output = entry.second (inputValue);
643
644 NS_TEST_ASSERT_MSG_EQ (output, expected,
645 "The builder free function for " << entry.first <<
646 " did not create a Length with the correct value");
647 }
648}
649
650void
652{
653 auto l = Length::TryParse (1, "");
654
655 AssertFalse (l.has_value (), "TryParse returned true on bad input");
656}
657
658void
660{
661 using TestInput = std::pair<double, std::string>;
662 using TestArgs = std::pair<double, double>;
663 std::map<TestInput, TestArgs> tests{
664 {{5, "m"}, {5, 0}},
665 {{5, " m"}, {5, 0}},
666 {{5, "kilometer"}, {5e3, 0}},
667 {{5, " kilometer"}, {5e3, 0}}
668 };
669
670 for (auto& entry : tests)
671 {
672 TestInput input = entry.first;
673 TestArgs args = entry.second;
674
675 auto l = Length::TryParse (input.first, input.second);
676
677 AssertTrue (l.has_value (), "TryParse returned false when expecting true");
678
679 std::stringstream stream;
680 stream << "Parsing input (" << input.first << ", " << input.second
681 << ") returned the wrong value";
682
683 NS_TEST_ASSERT_MSG_EQ_TOL (l->GetDouble (), args.first, args.second, stream.str ());
684 }
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 (),
699 "copy assignment failed");
700}
701
702void
704{
705 const double value = 5;
706
707 Length original (value, Unit::Meter);
708
709 Length copy;
710 copy = std::move (original);
711
712 NS_TEST_ASSERT_MSG_EQ (copy.GetDouble (), value,
713 "move assignment failed");
714}
715
716void
718{
719 Length::Quantity input (5, Unit::Kilometer);
720
721 Length l;
722 Length expected (input);
723
724 l = input;
725
726 NS_TEST_ASSERT_MSG_EQ (l, expected,
727 "quantity assignment failed");
728}
729
730void
732{
733 const double value = 5;
734 Length one (value, Unit::Meter);
735 Length two (one);
736
737 AssertTrue (one.IsEqual (two), "IsEqual returned false for equal lengths");
738}
739
740void
742{
743 const double value = 5;
744 Length one (value, Unit::Meter);
745 Length two ( value, Unit::Foot );
746
747 AssertFalse (one.IsEqual (two), "IsEqual returned true for unequal lengths");
748}
749
750void
752{
753 const double value = 5;
754 const double tolerance = 0.1;
755
756 Length one (value, Unit::Meter);
757 Length two ( (value + 0.1), Unit::Meter);
758
759 AssertTrue (one.IsEqual (two, tolerance),
760 "IsEqual returned false for almost equal lengths");
761}
762
763void
765{
766 const double value = 5;
767 const double tolerance = 0.01;
768
769 Length one (value, Unit::Meter);
770 Length two ( (value + 0.1), Unit::Meter);
771
772 AssertFalse (one.IsEqual (two, tolerance),
773 "IsEqual returned true for almost equal lengths");
774}
775
776void
778{
779 const double value = 5;
780
781 Length one (value, Unit::Meter);
782 Length two ( (value + 0.1), Unit::Meter);
783
784 AssertTrue (one.IsNotEqual (two),
785 "IsNotEqual returned false for not equal lengths");
786}
787
788void
790{
791 const double value = 5;
792
793 Length one (value, Unit::Meter);
794 Length two ( one );
795
796 AssertFalse (one.IsNotEqual (two),
797 "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),
833 "IsLess returned false for non equal lengths");
834}
835
836void
838{
839 const double value = 5;
840
841 Length one (value, Unit::Meter);
842 Length two ( one );
843
844 AssertFalse (one.IsLess (two),
845 "IsLess returned true for equal lengths");
846}
847
848void
850{
851 const double tolerance = 0.01;
852
853 Length one ( 5.1234, Unit::Meter );
854 Length two ( 5.1278, Unit::Meter );
855
856 AssertFalse (one.IsLess (two, tolerance),
857 "IsLess with tolerance returned true");
858}
859
860void
862{
863 Length one (2.0, Unit::Meter);
864 Length two (1.0, Unit::Meter);
865
866 AssertTrue (one.IsGreater (two),
867 "IsGreater returned false");
868}
869
870void
872{
873 Length one (2.0, Unit::Meter);
874 Length two (1.0, Unit::Meter);
875
876 AssertFalse (two.IsGreater (one),
877 "IsGreater returned true");
878}
879
880void
882{
883 const double tolerance = 0.01;
884
885 Length one (5.1234, Unit::Meter);
886 Length two (5.1278, Unit::Meter);
887
888 AssertFalse (two.IsGreater (one, tolerance),
889 "IsGreater returned true");
890}
891
892void
894{
895 Length l (1.0, Unit::Meter);
896
897 std::stringstream stream;
898
899 stream << l;
900
901 NS_TEST_ASSERT_MSG_EQ (stream.str (), "1 m",
902 "unexpected output from operator<<");
903}
904
905void
907{
908 const double value = 5;
909
910 Length l;
911
912 std::stringstream stream;
913
914 stream << value << "m";
915
916 stream >> l;
917
918 NS_TEST_ASSERT_MSG_EQ (l.GetDouble (), value,
919 "unexpected length from operator>>");
920}
921
922template<class T>
923void
925 const T& unit,
926 const std::string& expectedOutput,
927 const std::string& context)
928{
929 const std::string msg = context + ": unexpected output when serializing length";
930
931 std::ostringstream stream;
932
933 stream << std::fixed
934 << std::setprecision (5)
935 << l.As (unit);
936
937 NS_TEST_ASSERT_MSG_EQ (stream.str (), expectedOutput, msg);
938}
939
940void
942{
943 Length l (1.0, Unit::Meter);
944
945 TestLengthSerialization (l, Unit::Nanometer, "1000000000.00000 nm", "nanometers");
946 TestLengthSerialization (l, Unit::Micrometer, "1000000.00000 um", "micrometers");
947 TestLengthSerialization (l, Unit::Millimeter, "1000.00000 mm", "millimeters");
948 TestLengthSerialization (l, Unit::Centimeter, "100.00000 cm", "centimeters");
949 TestLengthSerialization (l, Unit::Meter, "1.00000 m", "meters");
950 TestLengthSerialization (l, Unit::Kilometer, "0.00100 km", "kilometers");
951 TestLengthSerialization (l, Unit::NauticalMile, "0.00054 nmi", "nautical_mile");
952 TestLengthSerialization (l, Unit::Inch, "39.37008 in", "inches");
953 TestLengthSerialization (l, Unit::Foot, "3.28084 ft", "feet");
954 TestLengthSerialization (l, Unit::Yard, "1.09361 yd", "yards");
955 TestLengthSerialization (l, Unit::Mile, "0.00062 mi", "miles");
956}
957
958void
960{
961 const double value = 5;
962
963 Length one ( value, Unit::Meter );
964 Length two ( value, Unit::Meter );
965
966 AssertTrue ( one == two,
967 "operator== returned false for 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 AssertFalse ( one == two,
979 "operator== returned true for non equal lengths");
980}
981
982void
984{
985 const double value = 5;
986
987 Length one ( value, Unit::Meter );
988 Length two ( value, Unit::Kilometer);
989
990 AssertTrue ( one != two,
991 "operator!= returned false for non equal lengths");
992
993}
994
995void
997{
998 const double value = 5;
999
1000 Length one ( value, Unit::Meter );
1001 Length two ( value, Unit::Meter );
1002
1003 AssertFalse ( one != two,
1004 "operator!= returned true for equal lengths");
1005
1006}
1007
1008void
1010{
1011 const double value = 5;
1012
1013 Length one ( value, Unit::Meter );
1014 Length two ( value, Unit::Kilometer);
1015
1016 AssertTrue ( one < two,
1017 "operator< returned false for smaller length");
1018}
1019
1020void
1022{
1023 const double value = 5;
1024
1025 Length one ( value, Unit::Meter );
1026 Length two ( value, Unit::Kilometer);
1027
1028 AssertFalse ( two < one,
1029 "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 Length three ( one );
1040
1041 AssertTrue ( one <= two,
1042 "operator<= returned false for smaller length");
1043
1044 AssertTrue ( one <= three,
1045 "operator<= returned false for equal lengths");
1046}
1047
1048void
1050{
1051 const double value = 5;
1052
1053 Length one ( value, Unit::Meter );
1054 Length two ( value, Unit::Kilometer);
1055
1056 AssertFalse ( two <= one,
1057 "operator<= returned true for larger length");
1058}
1059
1060void
1062{
1063 const double value = 5;
1064
1065 Length one ( value, Unit::Meter );
1066 Length two ( value, Unit::Kilometer);
1067
1068 AssertTrue ( two > one,
1069 "operator> returned false for larger length");
1070}
1071
1072void
1074{
1075 const double value = 5;
1076
1077 Length one ( value, Unit::Meter );
1078 Length two ( value, Unit::Kilometer);
1079
1080 AssertFalse ( one > two,
1081 "operator> returned true for smaller length");
1082}
1083
1084void
1086{
1087 const double value = 5;
1088
1089 Length one ( value, Unit::Meter );
1090 Length two ( value, Unit::Kilometer);
1091 Length three ( one );
1092
1093 AssertTrue ( two >= one,
1094 "operator>= returned false for larger length");
1095
1096 AssertTrue ( one >= three,
1097 "operator>= returned false for equal lengths");
1098}
1099
1100void
1102{
1103 const double value = 5;
1104
1105 Length one ( value, Unit::Meter );
1106 Length two ( value, Unit::Kilometer);
1107
1108 AssertFalse ( one >= two,
1109 "operator>= returned true for smaller length");
1110}
1111
1112void
1114{
1115 const double value = 1;
1116 const double expectedOutput = 2;
1117
1118 Length one ( value, Unit::Meter );
1119 Length two ( value, Unit::Meter );
1120
1121 Length result = one + two;
1122
1123 NS_TEST_ASSERT_MSG_EQ ( one.GetDouble (), value,
1124 "operator+ modified first operand");
1125 NS_TEST_ASSERT_MSG_EQ ( two.GetDouble (), value,
1126 "operator+ modified second operand");
1127 NS_TEST_ASSERT_MSG_EQ ( result.GetDouble (), expectedOutput,
1128 "operator+ returned incorrect value");
1129}
1130
1131void
1133{
1134 const double value = 1;
1135 const double expectedOutput = 2;
1136
1137 Length one ( value, Unit::Meter );
1138
1139 Length result = one + Length::Quantity (value, Unit::Meter);
1140
1141 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1142 "operator+ modified first operand");
1143 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1144 "operator+ returned incorrect value");
1145}
1146
1147void
1149{
1150 const double value = 1;
1151 const double expectedOutput = 2;
1152
1153 Length one ( value, Unit::Meter );
1154
1155 Length result = Length::Quantity (value, Unit::Meter) + one;
1156
1157 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1158 "operator+ modified first operand");
1159 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1160 "operator+ returned incorrect value");
1161}
1162
1163void
1165{
1166 const double value = 1;
1167 const double expectedOutput = 0;
1168
1169 Length one ( value, Unit::Meter );
1170 Length two ( value, Unit::Meter );
1171
1172 Length result = one - two;
1173
1174 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1175 "operator- modified first operand");
1176 NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), value,
1177 "operator- modified second operand");
1178 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1179 "operator- returned incorrect value");
1180}
1181
1182void
1184{
1185 const double value = 1;
1186 const double expectedOutput = 0;
1187
1188 Length one ( value, Unit::Meter );
1189
1190 Length result = one - Length::Quantity ( value, Unit::Meter);
1191
1192 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1193 "operator- modified first operand");
1194 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1195 "operator- returned incorrect value");
1196}
1197
1198void
1200{
1201 const double value = 1;
1202 const double expectedOutput = 0;
1203
1204 Length one ( value, Unit::Meter );
1205
1206 Length result = Length::Quantity (value, Unit::Meter) - one;
1207
1208 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1209 "operator- modified second operand");
1210 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1211 "operator- returned incorrect value");
1212}
1213
1214void
1216{
1217 const double value = 1;
1218 const double scalar = 5;
1219 const double expectedOutput = value * scalar;
1220
1221 Length one ( value, Unit::Meter );
1222 Length result = one * scalar;
1223
1224 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1225 "operator* modified first operand");
1226 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1227 "operator* returned incorrect value");
1228}
1229
1230void
1232{
1233 const double value = 1;
1234 const double scalar = 5;
1235 const double expectedOutput = value * scalar;
1236
1237 Length one ( value, Unit::Meter );
1238 Length result = scalar * one;
1239
1240 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1241 "operator* modified second operand");
1242 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1243 "operator* returned incorrect value");
1244}
1245
1246void
1248{
1249 const double value = 10;
1250 const double scalar = 5;
1251 const double expectedOutput = value / scalar;
1252
1253 Length one ( value, Unit::Meter );
1254 Length result = one / scalar;
1255
1256 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), value,
1257 "operator/ modified first operand");
1258 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedOutput,
1259 "operator/ returned incorrect value");
1260}
1261
1262void
1264{
1265 const double valueOne = 100;
1266 const double valueTwo = 2;
1267 const double expectedOutput = valueOne / valueTwo;
1268
1269 Length one ( valueOne, Unit::Meter );
1270 Length two ( valueTwo, Unit::Meter );
1271
1272 double result = one / two;
1273
1274 NS_TEST_ASSERT_MSG_EQ (one.GetDouble (), valueOne,
1275 "operator/ modified first operand");
1276 NS_TEST_ASSERT_MSG_EQ (two.GetDouble (), valueTwo,
1277 "operator/ modified second operand");
1278 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1279 "operator/ returned incorrect value");
1280
1281}
1282
1283void
1285{
1286 const double value = 1;
1287
1288 Length one ( value, Unit::Meter );
1289 Length two;
1290
1291 double result = one / two;
1292
1293 AssertTrue ( std::isnan (result),
1294 "operator/ did not return NaN when dividing by zero");
1295}
1296
1297void
1299{
1300 const double topValue = 100;
1301 const double bottomValue = 20;
1302 const int64_t expectedOutput = 5;
1303
1304 Length numerator (topValue, Unit::Meter);
1305 Length denominator (bottomValue, Unit::Meter);
1306
1307 auto result = Div (numerator, denominator);
1308
1309 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1310 "Div() returned an incorrect value");
1311}
1312
1313void
1315{
1316 const double topValue = 100;
1317 const double bottomValue = 20;
1318 const int64_t expectedOutput = 5;
1319 const int64_t expectedRemainder = 0;
1320
1321 Length numerator (topValue, Unit::Meter);
1322 Length denominator (bottomValue, Unit::Meter);
1323 Length remainder;
1324
1325 auto result = Div (numerator, denominator, &remainder);
1326
1327 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1328 "Div() returned an incorrect value");
1329 NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
1330 "Div() returned an incorrect remainder");
1331}
1332
1333void
1335{
1336 const double topValue = 110;
1337 const double bottomValue = 20;
1338 const int64_t expectedOutput = 5;
1339 const int64_t expectedRemainder = 10;
1340
1341 Length numerator (topValue, Unit::Meter);
1342 Length denominator (bottomValue, Unit::Meter);
1343 Length remainder;
1344
1345 auto result = Div (numerator, denominator, &remainder);
1346
1347 NS_TEST_ASSERT_MSG_EQ (result, expectedOutput,
1348 "Div() returned an incorrect value");
1349 NS_TEST_ASSERT_MSG_EQ (remainder.GetDouble (), expectedRemainder,
1350 "Div() returned an incorrect remainder");
1351}
1352
1353void
1355{
1356 Length numerator (10, Unit::Meter);
1357 Length denominator (2, Unit::Meter);
1358
1359 auto result = Mod (numerator, denominator);
1360
1361 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), 0,
1362 "Mod() returned a non zero value");
1363}
1364
1365void
1367{
1368 Length numerator (14, Unit::Meter);
1369 Length denominator (3, Unit::Meter);
1370 const double expectedValue = 2;
1371
1372 auto result = Mod (numerator, denominator);
1373
1374 NS_TEST_ASSERT_MSG_EQ (result.GetDouble (), expectedValue,
1375 "Mod() returned the wrong value");
1376}
1377
1378void
1380{
1382
1384
1386
1388
1390
1392
1404
1405#ifdef HAVE_BOOST_UNITS
1406 TestConstructLengthFromBoostUnits ();
1407#endif
1408
1410
1413
1417
1432
1434
1436
1449
1461
1465
1468}
1469
1476{
1477public:
1482 : TestCase ("length-value-tests")
1483 {}
1484
1489 {}
1490
1491private:
1493 class TestObject : public Object
1494 {
1495 public:
1500 static TypeId GetTypeId ();
1501
1503 : m_length ()
1504 {}
1505
1506 virtual ~TestObject ()
1507 {}
1508
1509 private:
1511 };
1512
1513private:
1518
1523
1528
1532 void TestObjectAttribute ();
1533
1538
1539 // Inherited function
1540 virtual void DoRun ();
1541};
1542
1543TypeId
1545{
1546 static TypeId tid = TypeId ("LengthValueTestCase::TestObject")
1547 .SetParent<Object> ()
1548 .SetGroupName ("Test")
1549 .AddConstructor<TestObject> ()
1550 .AddAttribute ("Length",
1551 "Length value",
1552 LengthValue (),
1555 ;
1556
1557 return tid;
1558}
1559
1560void
1562{
1563 Length l = KiloMeters (2);
1564 LengthValue value (l);
1565
1566 NS_TEST_ASSERT_MSG_EQ (value.Get (), l, "Length attribute has wrong value");
1567}
1568
1569void
1571{
1573
1574 Length l = KiloMeters (2);
1575 LengthValue value (l);
1576
1577 std::string output = value.SerializeToString (checker);
1578
1579 NS_TEST_ASSERT_MSG_EQ (output, "2000 m",
1580 "Length attribute serialization has wrong output");
1581}
1582
1583void
1585{
1587
1588 Length l = KiloMeters (2);
1589 std::ostringstream stream;
1590 stream << l;
1591
1592 LengthValue value;
1593 bool result = value.DeserializeFromString (stream.str (), checker);
1594
1595 NS_TEST_ASSERT_MSG_EQ (result, true,
1596 "Length attribute deserialization failed");
1597 NS_TEST_ASSERT_MSG_EQ (value.Get (), l,
1598 "Length attribute has wrong value after deserialization");
1599}
1600
1601void
1603{
1604 Length expected (5, Unit::Kilometer);
1605 Ptr<TestObject> obj = CreateObject<TestObject> ();
1606
1607 obj->SetAttribute ("Length", LengthValue (expected));
1608
1609 LengthValue val;
1610 obj->GetAttribute ("Length", val);
1611
1612 NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
1613 "Length attribute does not have expected value");
1614}
1615
1616void
1618{
1619 Length expected (5, Unit::Kilometer);
1620 Ptr<TestObject> obj = CreateObject<TestObject> ();
1621
1622 std::stringstream stream;
1623 stream << expected.As (Unit::Kilometer);
1624
1625 obj->SetAttribute ("Length", StringValue (stream.str()));
1626
1627 LengthValue val;
1628 obj->GetAttribute ("Length", val);
1629
1630 NS_TEST_ASSERT_MSG_EQ (val.Get (), expected,
1631 "Length attribute does not have expected value");
1632}
1633
1634void
1636{
1642}
1643
1649{
1650public:
1654 LengthTestSuite ();
1655};
1656
1658 : TestSuite ("length")
1659{
1660 AddTestCase ( new LengthTestCase (), TestCase::QUICK );
1661 AddTestCase ( new LengthValueTestCase (), TestCase::QUICK );
1662}
1663
1668
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:373
bool IsGreater(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is less in value than this instance.
Definition: length.cc:349
bool IsEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is equal in value to this instance.
Definition: length.cc:310
Quantity As(Unit unit) const
Create a Quantity in a specific unit from a Length.
Definition: length.cc:379
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:333
bool IsNotEqual(const Length &other, double tolerance=DEFAULT_TOLERANCE) const
Check if other is not equal in value to this instance.
Definition: length.cc:325
AttributeValue implementation for Length.
Definition: length.h:622
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:622
Length KiloMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:808
Length MilliMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:790
Length NauticalMiles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:814
Length Yards(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:832
Length Feet(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:826
Length Mod(const Length &numerator, const Length &denominator)
Calculate the amount remaining after dividing two lengths.
Definition: length.cc:493
Length MicroMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:784
Length Miles(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:838
Length Meters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:802
Length CentiMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:796
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:474
Length NanoMeters(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:778
Length Inches(double value)
Construct a length from a value in the indicated unit.
Definition: length.cc:820
#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.