blob: 607d69b18f599d94d5f30cbb41b9f9dfe89f8bcf [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/shell/platform/common/cpp/client_wrapper/testing/encodable_value_utils.h"
#include <cmath>
namespace flutter {
namespace testing {
bool EncodableValuesAreEqual(const EncodableValue& a, const EncodableValue& b) {
if (a.type() != b.type()) {
return false;
}
switch (a.type()) {
case EncodableValue::Type::kNull:
return true;
case EncodableValue::Type::kBool:
return a.BoolValue() == b.BoolValue();
case EncodableValue::Type::kInt:
return a.IntValue() == b.IntValue();
case EncodableValue::Type::kLong:
return a.LongValue() == b.LongValue();
case EncodableValue::Type::kDouble:
// This is a crude epsilon, but fine for the values in the unit tests.
return std::abs(a.DoubleValue() - b.DoubleValue()) < 0.0001l;
case EncodableValue::Type::kString:
return a.StringValue() == b.StringValue();
case EncodableValue::Type::kByteList:
return a.ByteListValue() == b.ByteListValue();
case EncodableValue::Type::kIntList:
return a.IntListValue() == b.IntListValue();
case EncodableValue::Type::kLongList:
return a.LongListValue() == b.LongListValue();
case EncodableValue::Type::kDoubleList:
return a.DoubleListValue() == b.DoubleListValue();
case EncodableValue::Type::kList: {
const auto& a_list = a.ListValue();
const auto& b_list = b.ListValue();
if (a_list.size() != b_list.size()) {
return false;
}
for (size_t i = 0; i < a_list.size(); ++i) {
if (!EncodableValuesAreEqual(a_list[0], b_list[0])) {
return false;
}
}
return true;
}
case EncodableValue::Type::kMap: {
const auto& a_map = a.MapValue();
const auto& b_map = b.MapValue();
if (a_map.size() != b_map.size()) {
return false;
}
// Store references to all the keys in |b|.
std::vector<const EncodableValue*> unmatched_b_keys;
for (auto& pair : b_map) {
unmatched_b_keys.push_back(&pair.first);
}
// For each key,value in |a|, see if any of the not-yet-matched key,value
// pairs in |b| match by value; if so, remove that match and continue.
for (const auto& pair : a_map) {
bool found_match = false;
for (size_t i = 0; i < unmatched_b_keys.size(); ++i) {
const EncodableValue& b_key = *unmatched_b_keys[i];
if (EncodableValuesAreEqual(pair.first, b_key) &&
EncodableValuesAreEqual(pair.second, b_map.at(b_key))) {
found_match = true;
unmatched_b_keys.erase(unmatched_b_keys.begin() + i);
break;
}
}
if (!found_match) {
return false;
}
}
// If all entries had matches, consider the maps equal.
return true;
}
}
assert(false);
return false;
}
} // namespace testing
} // namespace flutter