fix units router and allow the test cases to compare double numbers with precision
authorYounies Mahmoud <younies.mahmoud@gmail.com>
Mon, 8 Jun 2020 17:52:07 +0000 (19:52 +0200)
committerYounies Mahmoud <younies.mahmoud@gmail.com>
Mon, 8 Jun 2020 17:52:07 +0000 (19:52 +0200)
icu4c/source/i18n/complexunitsconverter.cpp
icu4c/source/i18n/unitsrouter.cpp
icu4c/source/test/intltest/intltest.cpp
icu4c/source/test/intltest/unitstest.cpp

index b2324104101cdb1ad67c89f0e9ce89d478de6445..5739f86048dea35d50a85a8f8e1623fabdbb2eeb 100644 (file)
@@ -24,7 +24,8 @@ ComplexUnitsConverter::ComplexUnitsConverter(const MeasureUnit inputUnit, const
         singleUnitsInOrder.emplaceBack(singleUnits[i]);
     }
 
-    ComplexUnitsConverter(inputUnit, std::move(singleUnitsInOrder), ratesInfo, status);
+    *this = ComplexUnitsConverter(inputUnit, std::move(singleUnitsInOrder),
+                                  ratesInfo, status);
 
     // TODO(younies): question from Hugo: is this check appropriate? The
     // U_ASSERT in greaterThanOrEqual suggests this should be an invariant for
@@ -42,21 +43,21 @@ ComplexUnitsConverter::ComplexUnitsConverter(const MeasureUnit inputUnit,
         return;
     }
 
-    MaybeStackVector<UnitConverter> converters;
     for (int i = 0, n = outputUnits.length(); i < n; i++) {
-        if (i == 0) { // first element
-            converters.emplaceBack(inputUnit, *outputUnits[i], ratesInfo, status);
+      if (i == 0) { // first element
+        unitConverters_.emplaceBack(inputUnit, *outputUnits[i], ratesInfo,
+                                    status);
 
-        } else {
-            converters.emplaceBack(*outputUnits[i - 1], *outputUnits[i], ratesInfo, status);
-        }
+      } else {
+        unitConverters_.emplaceBack(*outputUnits[i - 1], *outputUnits[i],
+                                    ratesInfo, status);
+      }
 
         if (U_FAILURE(status)) break;
     }
 
     if (U_FAILURE(status)) return;
 
-    unitConverters_.appendAll(converters, status);
     units_.appendAll(outputUnits, status);
 }
 
index a180220023b328dea51cd3a589e8567b2eaad6f5..dfab7929a678a93a451f2f39bf17cde7e9ed8321 100644 (file)
@@ -38,8 +38,12 @@ UnitsRouter::UnitsRouter(MeasureUnit inputUnit, StringPiece region, StringPiece
         const auto &preference = *unitPreferences[i];
         MeasureUnit complexTargetUnit = MeasureUnit::forIdentifier(preference.unit.data(), status);
 
-        if (U_FAILURE(status)) { return; }
-        converterPreferences_.emplaceBack(inputUnit, complexTargetUnit, preference.geq, conversionRates,
+        if (U_FAILURE(status)) {
+          return;
+        }
+        
+        converterPreferences_.emplaceBack(inputUnit, complexTargetUnit,
+                                          preference.geq, conversionRates,
                                           status);
         if (U_FAILURE(status)) {
             fprintf(
index 7c6d7a6cd897d64c7203435eb58a05feaa6dac39..993222b244823ba1dc81f17f0fee5550cb3c30b5 100644 (file)
@@ -2177,7 +2177,11 @@ UBool IntlTest::assertNotEquals(const char* message,
 // http://junit.sourceforge.net/javadoc/org/junit/Assert.html#assertEquals(java.lang.String,%20double,%20double,%20double)
 UBool IntlTest::assertEqualsNear(const char *message, double expected, double actual, double precision) {
     double diff = std::abs(expected - actual);
-    double diffPercent = expected != 0? diff / expected : diff; // If the expected is equals zero, we
+    double diffPercent =
+        expected != 0 ? diff / expected
+                      : diff; // If the expected is equals zero, we assume that
+                              // the `diffPercent` is equal to the difference
+                              // between the actual and the expected
 
     if (diffPercent > precision) {
         errln((UnicodeString) "FAIL: " + message + "; got " + actual + "; expected " + expected);
index ca8e3bd1f8c64a0bcef1ad6a37f1bdfcdcd94f46..bed4501ec3dc1f395d606adf85987953b3a51af2 100644 (file)
@@ -6,6 +6,7 @@
 #if !UCONFIG_NO_FORMATTING
 
 #include <iostream>
+#include <cmath> 
 
 #include "charstr.h"
 #include "cmemory.h"
@@ -502,7 +503,7 @@ class ExpectedOutput {
         _skippedFields++;
         if (_skippedFields < 2) {
             // We are happy skipping one field per output unit: we want to skip
-            // rational fraction fiels like "11 / 10".
+            // rational fraction files like "11 / 10".
             errorCode = U_ZERO_ERROR;
             return;
         } else {
@@ -527,7 +528,7 @@ class ExpectedOutput {
 };
 
 void checkOutput(UnitsTest *unitsTest, const char *msg, ExpectedOutput expected,
-                  const MaybeStackVector<Measure> &actual) {
+                  const MaybeStackVector<Measure> &actual, double precision) {
     IcuTestErrorCode status(*unitsTest, "checkOutput");
     bool success = true;
     if (expected._compoundCount != actual.length()) {
@@ -537,10 +538,16 @@ void checkOutput(UnitsTest *unitsTest, const char *msg, ExpectedOutput expected,
         if (i >= expected._compoundCount) {
             break;
         }
-        if (expected._amounts[i] != actual[i]->getNumber().getDouble(status)) {
-            success = false;
-            break;
+
+        double diff = std::abs(expected._amounts[i] -
+                               actual[i]->getNumber().getDouble(status));
+        double diffPercent =
+            expected._amounts[i] != 0 ? diff / expected._amounts[i] : diff;
+        if (diffPercent > precision) {
+          success = false;
+          break;
         }
+
         if (expected._measureUnits[i] != actual[i]->getUnit()) {
             success = false;
             break;
@@ -633,7 +640,7 @@ void unitPreferencesTestDataLineFn(void *context, char *fields[][2], int32_t fie
     if (status.errIfFailureAndReset("Failure before router.route")) { return; }
     MaybeStackVector<Measure> result = router.route(inputAmount, status);
     if (status.errIfFailureAndReset("router.route(inputAmount, ...)")) { return; }
-    checkOutput(unitsTest, msg.data(), expected, result);
+    checkOutput(unitsTest, msg.data(), expected, result, 0.0001);
 }
 
 /**