aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/core/test/firebase/firestore/model
diff options
context:
space:
mode:
authorGravatar zxu <zxu@google.com>2018-01-25 09:14:19 -0500
committerGravatar GitHub <noreply@github.com>2018-01-25 09:14:19 -0500
commitbfa0e40795ba676fd02d616794cce1c9b2d6a95f (patch)
tree875e86ca1282c275a7f4ad68d03dbc0a2fb22b45 /Firestore/core/test/firebase/firestore/model
parent1f772120365641eb66f0cc9db9975721c8285d6e (diff)
Implement the rest of FieldValue types for C++ (#687)
* implement FieldValue for null and boolean. * Implement number and string FieldValue. * Implement object FieldValue. * implement timestamp FieldValue. * Implement number and string FieldValue. * implement public type `Blob` and `GeoPoint` * implement Blob FieldValue * Implement GeoPoint FieldValue * refactoring `Blob`
Diffstat (limited to 'Firestore/core/test/firebase/firestore/model')
-rw-r--r--Firestore/core/test/firebase/firestore/model/CMakeLists.txt1
-rw-r--r--Firestore/core/test/firebase/firestore/model/field_value_test.cc300
-rw-r--r--Firestore/core/test/firebase/firestore/model/timestamp_test.cc49
3 files changed, 349 insertions, 1 deletions
diff --git a/Firestore/core/test/firebase/firestore/model/CMakeLists.txt b/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
index 31fe040..9153a57 100644
--- a/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
+++ b/Firestore/core/test/firebase/firestore/model/CMakeLists.txt
@@ -16,6 +16,7 @@ cc_test(
firebase_firestore_model_test
SOURCES
field_value_test.cc
+ timestamp_test.cc
DEPENDS
firebase_firestore_model
)
diff --git a/Firestore/core/test/firebase/firestore/model/field_value_test.cc b/Firestore/core/test/firebase/firestore/model/field_value_test.cc
index 1194e63..a006d46 100644
--- a/Firestore/core/test/firebase/firestore/model/field_value_test.cc
+++ b/Firestore/core/test/firebase/firestore/model/field_value_test.cc
@@ -26,6 +26,14 @@ namespace model {
using Type = FieldValue::Type;
+namespace {
+
+const uint8_t* Bytes(const char* value) {
+ return reinterpret_cast<const uint8_t*>(value);
+}
+
+} // namespace
+
TEST(FieldValue, NullType) {
const FieldValue value = FieldValue::NullValue();
EXPECT_EQ(Type::Null, value.type());
@@ -42,6 +50,107 @@ TEST(FieldValue, BooleanType) {
EXPECT_TRUE(false_value < true_value);
}
+TEST(FieldValue, NumberType) {
+ const FieldValue nan_value = FieldValue::NanValue();
+ const FieldValue integer_value = FieldValue::IntegerValue(10L);
+ const FieldValue double_value = FieldValue::DoubleValue(10.1);
+ EXPECT_EQ(Type::Double, nan_value.type());
+ EXPECT_EQ(Type::Long, integer_value.type());
+ EXPECT_EQ(Type::Double, double_value.type());
+ EXPECT_TRUE(nan_value < integer_value);
+ EXPECT_TRUE(nan_value < double_value);
+ EXPECT_FALSE(nan_value < nan_value);
+ EXPECT_FALSE(integer_value < nan_value);
+ EXPECT_FALSE(integer_value < nan_value);
+ EXPECT_TRUE(integer_value < double_value); // 10 < 10.1
+ EXPECT_FALSE(double_value < integer_value);
+ EXPECT_FALSE(integer_value < integer_value);
+ EXPECT_FALSE(double_value < double_value);
+
+ // Number comparison craziness
+ // Integers
+ EXPECT_TRUE(FieldValue::IntegerValue(1L) < FieldValue::IntegerValue(2L));
+ EXPECT_FALSE(FieldValue::IntegerValue(1L) < FieldValue::IntegerValue(1L));
+ EXPECT_FALSE(FieldValue::IntegerValue(2L) < FieldValue::IntegerValue(1L));
+ // Doubles
+ EXPECT_TRUE(FieldValue::DoubleValue(1.0) < FieldValue::DoubleValue(2.0));
+ EXPECT_FALSE(FieldValue::DoubleValue(1.0) < FieldValue::DoubleValue(1.0));
+ EXPECT_FALSE(FieldValue::DoubleValue(2.0) < FieldValue::DoubleValue(1.0));
+ EXPECT_TRUE(FieldValue::NanValue() < FieldValue::DoubleValue(1.0));
+ EXPECT_FALSE(FieldValue::NanValue() < FieldValue::NanValue());
+ EXPECT_FALSE(FieldValue::DoubleValue(1.0) < FieldValue::NanValue());
+ // Mixed
+ EXPECT_TRUE(FieldValue::DoubleValue(-1e20) <
+ FieldValue::IntegerValue(LLONG_MIN));
+ EXPECT_FALSE(FieldValue::DoubleValue(1e20) <
+ FieldValue::IntegerValue(LLONG_MAX));
+ EXPECT_TRUE(FieldValue::DoubleValue(1.234) < FieldValue::IntegerValue(2L));
+ EXPECT_FALSE(FieldValue::DoubleValue(2.345) < FieldValue::IntegerValue(1L));
+ EXPECT_FALSE(FieldValue::DoubleValue(1.0) < FieldValue::IntegerValue(1L));
+ EXPECT_FALSE(FieldValue::DoubleValue(1.234) < FieldValue::IntegerValue(1L));
+ EXPECT_FALSE(FieldValue::IntegerValue(LLONG_MIN) <
+ FieldValue::DoubleValue(-1e20));
+ EXPECT_TRUE(FieldValue::IntegerValue(LLONG_MAX) <
+ FieldValue::DoubleValue(1e20));
+ EXPECT_FALSE(FieldValue::IntegerValue(1) < FieldValue::DoubleValue(1.0));
+ EXPECT_TRUE(FieldValue::IntegerValue(1) < FieldValue::DoubleValue(1.234));
+}
+
+TEST(FieldValue, TimestampType) {
+ const FieldValue o = FieldValue::TimestampValue(Timestamp());
+ const FieldValue a = FieldValue::TimestampValue({100, 0});
+ const FieldValue b = FieldValue::TimestampValue({200, 0});
+ EXPECT_EQ(Type::Timestamp, a.type());
+ EXPECT_TRUE(o < a);
+ EXPECT_TRUE(a < b);
+ EXPECT_FALSE(a < a);
+ const FieldValue c = FieldValue::ServerTimestampValue({100, 0});
+ const FieldValue d = FieldValue::ServerTimestampValue({200, 0}, {300, 0});
+ EXPECT_EQ(Type::ServerTimestamp, c.type());
+ EXPECT_EQ(Type::ServerTimestamp, d.type());
+ EXPECT_TRUE(c < d);
+ EXPECT_FALSE(c < c);
+ // Mixed
+ EXPECT_TRUE(o < c);
+ EXPECT_TRUE(a < c);
+ EXPECT_TRUE(b < c);
+ EXPECT_TRUE(b < d);
+ EXPECT_FALSE(c < o);
+ EXPECT_FALSE(c < a);
+ EXPECT_FALSE(c < b);
+ EXPECT_FALSE(d < b);
+}
+
+TEST(FieldValue, StringType) {
+ const FieldValue a = FieldValue::StringValue("abc");
+ std::string xyz("xyz");
+ const FieldValue b = FieldValue::StringValue(xyz);
+ const FieldValue c = FieldValue::StringValue(std::move(xyz));
+ EXPECT_EQ(Type::String, a.type());
+ EXPECT_EQ(Type::String, b.type());
+ EXPECT_EQ(Type::String, c.type());
+ EXPECT_TRUE(a < b);
+ EXPECT_FALSE(a < a);
+}
+
+TEST(FieldValue, BlobType) {
+ const FieldValue a = FieldValue::BlobValue(Bytes("abc"), 4);
+ const FieldValue b = FieldValue::BlobValue(Bytes("def"), 4);
+ EXPECT_EQ(Type::Blob, a.type());
+ EXPECT_EQ(Type::Blob, b.type());
+ EXPECT_TRUE(a < b);
+ EXPECT_FALSE(a < a);
+}
+
+TEST(FieldValue, GeoPointType) {
+ const FieldValue a = FieldValue::GeoPointValue({1, 2});
+ const FieldValue b = FieldValue::GeoPointValue({3, 4});
+ EXPECT_EQ(Type::GeoPoint, a.type());
+ EXPECT_EQ(Type::GeoPoint, b.type());
+ EXPECT_TRUE(a < b);
+ EXPECT_FALSE(a < a);
+}
+
TEST(FieldValue, ArrayType) {
const FieldValue empty =
FieldValue::ArrayValue(std::vector<const FieldValue>{});
@@ -64,6 +173,29 @@ TEST(FieldValue, ArrayType) {
EXPECT_FALSE(large < small);
}
+TEST(FieldValue, ObjectType) {
+ const FieldValue empty =
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{});
+ std::map<const std::string, const FieldValue> object{
+ {"null", FieldValue::NullValue()},
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}};
+ // copy the map
+ const FieldValue small = FieldValue::ObjectValue(object);
+ std::map<const std::string, const FieldValue> another_object{
+ {"null", FieldValue::NullValue()}, {"true", FieldValue::FalseValue()}};
+ // move the array
+ const FieldValue large = FieldValue::ObjectValue(std::move(another_object));
+ EXPECT_EQ(Type::Object, empty.type());
+ EXPECT_EQ(Type::Object, small.type());
+ EXPECT_EQ(Type::Object, large.type());
+ EXPECT_TRUE(empty < small);
+ EXPECT_FALSE(small < empty);
+ EXPECT_FALSE(small < small);
+ EXPECT_TRUE(small < large);
+ EXPECT_FALSE(large < small);
+}
+
TEST(FieldValue, Copy) {
FieldValue clone = FieldValue::TrueValue();
const FieldValue null_value = FieldValue::NullValue();
@@ -82,6 +214,80 @@ TEST(FieldValue, Copy) {
clone = null_value;
EXPECT_EQ(FieldValue::NullValue(), clone);
+ const FieldValue nan_value = FieldValue::NanValue();
+ clone = nan_value;
+ EXPECT_EQ(FieldValue::NanValue(), clone);
+ EXPECT_EQ(FieldValue::NanValue(), nan_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::NanValue(), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue integer_value = FieldValue::IntegerValue(1L);
+ clone = integer_value;
+ EXPECT_EQ(FieldValue::IntegerValue(1L), clone);
+ EXPECT_EQ(FieldValue::IntegerValue(1L), integer_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::IntegerValue(1L), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue double_value = FieldValue::DoubleValue(1.0);
+ clone = double_value;
+ EXPECT_EQ(FieldValue::DoubleValue(1.0), clone);
+ EXPECT_EQ(FieldValue::DoubleValue(1.0), double_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::DoubleValue(1.0), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
+ clone = timestamp_value;
+ EXPECT_EQ(FieldValue::TimestampValue({100, 200}), clone);
+ EXPECT_EQ(FieldValue::TimestampValue({100, 200}), timestamp_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::TimestampValue({100, 200}), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue server_timestamp_value =
+ FieldValue::ServerTimestampValue({1, 2}, {3, 4});
+ clone = server_timestamp_value;
+ EXPECT_EQ(FieldValue::ServerTimestampValue({1, 2}, {3, 4}), clone);
+ EXPECT_EQ(FieldValue::ServerTimestampValue({1, 2}, {3, 4}),
+ server_timestamp_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::ServerTimestampValue({1, 2}, {3, 4}), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue string_value = FieldValue::StringValue("abc");
+ clone = string_value;
+ EXPECT_EQ(FieldValue::StringValue("abc"), clone);
+ EXPECT_EQ(FieldValue::StringValue("abc"), string_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::StringValue("abc"), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
+ clone = blob_value;
+ EXPECT_EQ(FieldValue::BlobValue(Bytes("abc"), 4), clone);
+ EXPECT_EQ(FieldValue::BlobValue(Bytes("abc"), 4), blob_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::BlobValue(Bytes("abc"), 4), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
+ clone = geo_point_value;
+ EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), clone);
+ EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), geo_point_value);
+ clone = clone;
+ EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
const FieldValue array_value =
FieldValue::ArrayValue(std::vector<const FieldValue>{
FieldValue::TrueValue(), FieldValue::FalseValue()});
@@ -98,6 +304,30 @@ TEST(FieldValue, Copy) {
clone);
clone = null_value;
EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue object_value =
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}});
+ clone = object_value;
+ EXPECT_EQ(
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}}),
+ clone);
+ EXPECT_EQ(
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}}),
+ object_value);
+ clone = clone;
+ EXPECT_EQ(
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}}),
+ clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
}
TEST(FieldValue, Move) {
@@ -113,6 +343,48 @@ TEST(FieldValue, Move) {
clone = FieldValue::NullValue();
EXPECT_EQ(FieldValue::NullValue(), clone);
+ FieldValue nan_value = FieldValue::NanValue();
+ clone = std::move(nan_value);
+ EXPECT_EQ(FieldValue::NanValue(), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ FieldValue integer_value = FieldValue::IntegerValue(1L);
+ clone = std::move(integer_value);
+ EXPECT_EQ(FieldValue::IntegerValue(1L), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ FieldValue double_value = FieldValue::DoubleValue(1.0);
+ clone = std::move(double_value);
+ EXPECT_EQ(FieldValue::DoubleValue(1.0), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
+ clone = std::move(timestamp_value);
+ EXPECT_EQ(FieldValue::TimestampValue({100, 200}), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ FieldValue string_value = FieldValue::StringValue("abc");
+ clone = std::move(string_value);
+ EXPECT_EQ(FieldValue::StringValue("abc"), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
+ clone = std::move(blob_value);
+ EXPECT_EQ(FieldValue::BlobValue(Bytes("abc"), 4), clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
+ clone = std::move(geo_point_value);
+ EXPECT_EQ(FieldValue::GeoPointValue({1, 2}), clone);
+ clone = null_value;
+ EXPECT_EQ(FieldValue::NullValue(), clone);
+
FieldValue array_value = FieldValue::ArrayValue(std::vector<const FieldValue>{
FieldValue::TrueValue(), FieldValue::FalseValue()});
clone = std::move(array_value);
@@ -121,15 +393,41 @@ TEST(FieldValue, Move) {
clone);
clone = FieldValue::NullValue();
EXPECT_EQ(FieldValue::NullValue(), clone);
+
+ FieldValue object_value =
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}});
+ clone = std::move(object_value);
+ EXPECT_EQ(
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>{
+ {"true", FieldValue::TrueValue()},
+ {"false", FieldValue::FalseValue()}}),
+ clone);
+ clone = FieldValue::NullValue();
+ EXPECT_EQ(FieldValue::NullValue(), clone);
}
TEST(FieldValue, CompareMixedType) {
const FieldValue null_value = FieldValue::NullValue();
const FieldValue true_value = FieldValue::TrueValue();
+ const FieldValue number_value = FieldValue::NanValue();
+ const FieldValue timestamp_value = FieldValue::TimestampValue({100, 200});
+ const FieldValue string_value = FieldValue::StringValue("abc");
+ const FieldValue blob_value = FieldValue::BlobValue(Bytes("abc"), 4);
+ const FieldValue geo_point_value = FieldValue::GeoPointValue({1, 2});
const FieldValue array_value =
FieldValue::ArrayValue(std::vector<const FieldValue>());
+ const FieldValue object_value =
+ FieldValue::ObjectValue(std::map<const std::string, const FieldValue>());
EXPECT_TRUE(null_value < true_value);
- EXPECT_TRUE(true_value < array_value);
+ EXPECT_TRUE(true_value < number_value);
+ EXPECT_TRUE(number_value < timestamp_value);
+ EXPECT_TRUE(timestamp_value < string_value);
+ EXPECT_TRUE(string_value < blob_value);
+ EXPECT_TRUE(blob_value < geo_point_value);
+ EXPECT_TRUE(geo_point_value < array_value);
+ EXPECT_TRUE(array_value < object_value);
}
TEST(FieldValue, CompareWithOperator) {
diff --git a/Firestore/core/test/firebase/firestore/model/timestamp_test.cc b/Firestore/core/test/firebase/firestore/model/timestamp_test.cc
new file mode 100644
index 0000000..55ee378
--- /dev/null
+++ b/Firestore/core/test/firebase/firestore/model/timestamp_test.cc
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2018 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "Firestore/core/src/firebase/firestore/model/timestamp.h"
+
+#include <vector>
+
+#include "gtest/gtest.h"
+
+namespace firebase {
+namespace firestore {
+namespace model {
+
+TEST(Timestamp, Getter) {
+ const Timestamp timestamp_zero;
+ EXPECT_EQ(0, timestamp_zero.seconds());
+ EXPECT_EQ(0, timestamp_zero.nanos());
+
+ const Timestamp timestamp(100, 200);
+ EXPECT_EQ(100, timestamp.seconds());
+ EXPECT_EQ(200, timestamp.nanos());
+
+ const Timestamp timestamp_now = Timestamp::Now();
+ EXPECT_LT(0, timestamp_now.seconds());
+ EXPECT_LE(0, timestamp_now.nanos());
+}
+
+TEST(Timestamp, Comparison) {
+ EXPECT_TRUE(Timestamp() < Timestamp(1, 2));
+ EXPECT_TRUE(Timestamp(1, 2) < Timestamp(2, 1));
+ EXPECT_TRUE(Timestamp(2, 1) < Timestamp(2, 2));
+}
+
+} // namespace model
+} // namespace firestore
+} // namespace firebase