1 module dunitconversion.tests.convertor;
2
3 import dunitconversion.convertor;
4 import dunitconversion.linearfunction;
5 import dunitconversion.conversionfamily;
6 import dunitconversion.conversionrule;
7 import dunitconversion.aliasdictionary;
8
9 import std.exception;
10 import std.math;
11 import std.algorithm;
12 import std.file;
13 import std.json;
14
15 unittest {
16 auto convertor = new UnitConvertor;
17
18 convertor.addConversionRule(ConversionRule("length", "m", "km", LinearFunction(0.001, 0)));
19
20 assert("length" in convertor.m_families);
21 assert("length" in convertor.m_baseUnitsByFamilies);
22 assert("m" in convertor.m_familiesByUnit);
23 assert("km" in convertor.m_familiesByUnit);
24 assert(convertor.m_familiesByUnit.length == 2);
25 assert(convertor.m_families.length == 1);
26 assert(convertor.m_baseUnitsByFamilies.length == 1);
27
28 convertor.addConversionRule(ConversionRule("length", "m", "cm", LinearFunction(100, 0)));
29 assert("m" in convertor.m_familiesByUnit);
30 assert("km" in convertor.m_familiesByUnit);
31 assert("cm" in convertor.m_familiesByUnit);
32 assert(convertor.m_familiesByUnit.length == 3);
33 assert(convertor.m_families.length == 1);
34 assert(convertor.m_baseUnitsByFamilies.length == 1);
35
36 convertor.addConversionRule(ConversionRule("length", "m", "mm", LinearFunction(1000, 0)));
37 assert("m" in convertor.m_familiesByUnit);
38 assert("km" in convertor.m_familiesByUnit);
39 assert("cm" in convertor.m_familiesByUnit);
40 assert("mm" in convertor.m_familiesByUnit);
41 assert(convertor.m_familiesByUnit.length == 4);
42 assert(convertor.m_families.length == 1);
43 assert(convertor.m_baseUnitsByFamilies.length == 1);
44
45 // assert("length" in convertor.m_families());
46
47 // passing existing family with a differnt base unit
48 assertThrown!Exception(
49 convertor.addConversionRule(ConversionRule("length", "km", "m", LinearFunction(1000, 0))));
50
51 // passing a different family with an existing base unit
52 assertThrown!Exception(
53 convertor.addConversionRule(ConversionRule("notlength", "m", "km", LinearFunction(0.001, 0))));
54
55 // passing the same conversion once again should work
56 convertor.addConversionRule(ConversionRule("length", "m", "mm", LinearFunction(1000, 0)));
57
58 // let's make sure that none of containers did change
59 assert(convertor.m_familiesByUnit.length == 4);
60 assert(convertor.m_families.length == 1);
61 assert(convertor.m_baseUnitsByFamilies.length == 1);
62
63 // note "min" here, since we have to make sure that all unit names are different
64 // we need to differ minutes from meters
65 convertor.addConversionRule(ConversionRule("time", "s", "min", LinearFunction(double(1) / 60, 0)));
66 assert("length" in convertor.m_families);
67 assert("time" in convertor.m_families);
68 assert(convertor.m_families.length == 2);
69 assert("m" in convertor.m_familiesByUnit);
70 assert("km" in convertor.m_familiesByUnit);
71 assert("cm" in convertor.m_familiesByUnit);
72 assert("mm" in convertor.m_familiesByUnit);
73 assert("s" in convertor.m_familiesByUnit);
74 assert("min" in convertor.m_familiesByUnit);
75 assert("length" in convertor.m_baseUnitsByFamilies);
76 assert("time" in convertor.m_baseUnitsByFamilies);
77 assert(convertor.m_baseUnitsByFamilies["length"] == "m");
78 assert(convertor.m_baseUnitsByFamilies["time"] == "s");
79
80 auto families = convertor.families();
81 assert(families.canFind("length"));
82 assert(families.canFind("time"));
83
84 auto units = convertor.units("length");
85 assert(units.length == 4);
86 assert(units.canFind("m"));
87 assert(units.canFind("km"));
88 assert(units.canFind("cm"));
89 assert(units.canFind("mm"));
90
91 assert(approxEqual(convertor.convert(0, "m", "km"), 0));
92 assert(approxEqual(convertor.convert(50, "m", "km"), 0.05));
93 assert(approxEqual(convertor.convert(50, "km", "m"), 50_000));
94 assert(approxEqual(convertor.convert(500, "cm", "m"), 5));
95 assert(approxEqual(convertor.convert(500, "cm", "km"), 0.005));
96 assert(approxEqual(convertor.convert(500, "m", "m"), 500));
97
98 auto conversions = convertor.conversions("m");
99 assert(conversions.canFind("m"));
100 assert(conversions.canFind("km"));
101 assert(conversions.canFind("cm"));
102 assert(conversions.canFind("mm"));
103 assert(conversions.length == 4);
104
105 conversions = convertor.conversions("mm");
106 assert(conversions.canFind("m"));
107 assert(conversions.canFind("km"));
108 assert(conversions.canFind("cm"));
109 assert(conversions.canFind("mm"));
110 assert(conversions.length == 4);
111
112 conversions = convertor.conversions("mmmm");
113 assert(conversions is null);
114
115 assert(convertor.family("m") == "length");
116 assert(convertor.family("km") == "length");
117 assertThrown!Exception(convertor.family("mmmmm"));
118 }
119
120 unittest {
121 auto convertor = new UnitConvertor;
122
123 convertor.loadFromJson(parseJSON(readText("./test/conversion_rules.json")));
124 convertor.loadAliasesFromJson(parseJSON(readText("./test/aliases.json")));
125
126 // conversion to an actual unit
127 assert(approxEqual(convertor.convert(0, "m", "km"), 0));
128 assert(approxEqual(convertor.convert(50, "m", "km"), 0.05));
129 assert(approxEqual(convertor.convert(50, "km", "m"), 50_000));
130 assert(approxEqual(convertor.convert(500, "cm", "m"), 5));
131 assert(approxEqual(convertor.convert(500, "cm", "km"), 0.005));
132
133 assert(approxEqual(convertor.convert(50, "m/s", "km/h"), 180));
134 assert(approxEqual(convertor.convert(50, "m/s", "kmph"), 180));
135 assert(approxEqual(convertor.convert(50, "m/s", "kmh"), 180));
136 assert(approxEqual(convertor.convert(50, "mps", "km/h"), 180));
137 assert(approxEqual(convertor.convert(50, "mps", "kmph"), 180));
138 assert(approxEqual(convertor.convert(50, "mps", "kmh"), 180));
139
140 assert(approxEqual(convertor.convert(0, "meter", "km"), 0));
141 assert(approxEqual(convertor.convert(50, "meters", "km"), 0.05));
142
143 assert(approxEqual(convertor.convert(100, "C", "K"), 373.15));
144
145 assert(approxEqual(convertor.convert(-40, "C", "F"), -40));
146
147 assert(convertor.family("m") == "length");
148 assert(convertor.family("km") == "length");
149
150 // should retrieve correct family for unit aliases as well
151 assert(convertor.family("meter") == "length");
152 assert(convertor.family("meters") == "length");
153
154 assertThrown!Exception(convertor.family("mmmmm"));
155 }