|
15 | 15 | // specific language governing permissions and limitations |
16 | 16 | // under the License. |
17 | 17 |
|
| 18 | +#include <limits> |
18 | 19 | #include <memory> |
| 20 | +#include <ostream> |
19 | 21 | #include <string> |
20 | 22 | #include <unordered_set> |
21 | 23 | #include <utility> |
@@ -96,6 +98,12 @@ TYPED_TEST(TestNumericScalar, Basics) { |
96 | 98 | ASSERT_FALSE(one->Equals(ScalarType(2))); |
97 | 99 | ASSERT_TRUE(two->Equals(ScalarType(2))); |
98 | 100 | ASSERT_FALSE(two->Equals(ScalarType(3))); |
| 101 | + |
| 102 | + ASSERT_TRUE(null->ApproxEquals(*null_value)); |
| 103 | + ASSERT_TRUE(one->ApproxEquals(ScalarType(1))); |
| 104 | + ASSERT_FALSE(one->ApproxEquals(ScalarType(2))); |
| 105 | + ASSERT_TRUE(two->ApproxEquals(ScalarType(2))); |
| 106 | + ASSERT_FALSE(two->ApproxEquals(ScalarType(3))); |
99 | 107 | } |
100 | 108 |
|
101 | 109 | TYPED_TEST(TestNumericScalar, Hashing) { |
@@ -127,6 +135,199 @@ TYPED_TEST(TestNumericScalar, MakeScalar) { |
127 | 135 | ASSERT_EQ(ScalarType(3), *three); |
128 | 136 | } |
129 | 137 |
|
| 138 | +template <typename T> |
| 139 | +class TestRealScalar : public ::testing::Test { |
| 140 | + public: |
| 141 | + using CType = typename T::c_type; |
| 142 | + using ScalarType = typename TypeTraits<T>::ScalarType; |
| 143 | + |
| 144 | + void SetUp() { |
| 145 | + type_ = TypeTraits<T>::type_singleton(); |
| 146 | + |
| 147 | + scalar_val_ = std::make_shared<ScalarType>(static_cast<CType>(1)); |
| 148 | + ASSERT_TRUE(scalar_val_->is_valid); |
| 149 | + |
| 150 | + scalar_other_ = std::make_shared<ScalarType>(static_cast<CType>(1.1)); |
| 151 | + ASSERT_TRUE(scalar_other_->is_valid); |
| 152 | + |
| 153 | + const CType nan_value = std::numeric_limits<CType>::quiet_NaN(); |
| 154 | + scalar_nan_ = std::make_shared<ScalarType>(nan_value); |
| 155 | + ASSERT_TRUE(scalar_nan_->is_valid); |
| 156 | + |
| 157 | + const CType other_nan_value = std::numeric_limits<CType>::quiet_NaN(); |
| 158 | + scalar_other_nan_ = std::make_shared<ScalarType>(other_nan_value); |
| 159 | + ASSERT_TRUE(scalar_other_nan_->is_valid); |
| 160 | + } |
| 161 | + |
| 162 | + void TestNanEquals() { |
| 163 | + EqualOptions options = EqualOptions::Defaults(); |
| 164 | + ASSERT_FALSE(scalar_nan_->Equals(*scalar_val_, options)); |
| 165 | + ASSERT_FALSE(scalar_nan_->Equals(*scalar_nan_, options)); |
| 166 | + ASSERT_FALSE(scalar_nan_->Equals(*scalar_other_nan_, options)); |
| 167 | + |
| 168 | + options = options.nans_equal(true); |
| 169 | + ASSERT_FALSE(scalar_nan_->Equals(*scalar_val_, options)); |
| 170 | + ASSERT_TRUE(scalar_nan_->Equals(*scalar_nan_, options)); |
| 171 | + ASSERT_TRUE(scalar_nan_->Equals(*scalar_other_nan_, options)); |
| 172 | + } |
| 173 | + |
| 174 | + void TestApproxEquals() { |
| 175 | + // The scalars are unequal with the small delta |
| 176 | + EqualOptions options = EqualOptions::Defaults().atol(0.05); |
| 177 | + ASSERT_FALSE(scalar_val_->ApproxEquals(*scalar_other_, options)); |
| 178 | + ASSERT_FALSE(scalar_other_->ApproxEquals(*scalar_val_, options)); |
| 179 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_val_, options)); |
| 180 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_other_nan_, options)); |
| 181 | + |
| 182 | + // After enlarging the delta, they become equal |
| 183 | + options = options.atol(0.15); |
| 184 | + ASSERT_TRUE(scalar_val_->ApproxEquals(*scalar_other_, options)); |
| 185 | + ASSERT_TRUE(scalar_other_->ApproxEquals(*scalar_val_, options)); |
| 186 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_val_, options)); |
| 187 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_other_nan_, options)); |
| 188 | + |
| 189 | + options = options.nans_equal(true); |
| 190 | + ASSERT_TRUE(scalar_val_->ApproxEquals(*scalar_other_, options)); |
| 191 | + ASSERT_TRUE(scalar_other_->ApproxEquals(*scalar_val_, options)); |
| 192 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_val_, options)); |
| 193 | + ASSERT_TRUE(scalar_nan_->ApproxEquals(*scalar_other_nan_, options)); |
| 194 | + |
| 195 | + options = options.atol(0.05); |
| 196 | + ASSERT_FALSE(scalar_val_->ApproxEquals(*scalar_other_, options)); |
| 197 | + ASSERT_FALSE(scalar_other_->ApproxEquals(*scalar_val_, options)); |
| 198 | + ASSERT_FALSE(scalar_nan_->ApproxEquals(*scalar_val_, options)); |
| 199 | + ASSERT_TRUE(scalar_nan_->ApproxEquals(*scalar_other_nan_, options)); |
| 200 | + } |
| 201 | + |
| 202 | + void TestStructOf() { |
| 203 | + auto ty = struct_({field("float", type_)}); |
| 204 | + |
| 205 | + StructScalar struct_val({scalar_val_}, ty); |
| 206 | + StructScalar struct_other_val({scalar_other_}, ty); |
| 207 | + StructScalar struct_nan({scalar_nan_}, ty); |
| 208 | + StructScalar struct_other_nan({scalar_other_nan_}, ty); |
| 209 | + |
| 210 | + EqualOptions options = EqualOptions::Defaults().atol(0.05); |
| 211 | + ASSERT_FALSE(struct_val.Equals(struct_other_val, options)); |
| 212 | + ASSERT_FALSE(struct_other_val.Equals(struct_val, options)); |
| 213 | + ASSERT_FALSE(struct_nan.Equals(struct_val, options)); |
| 214 | + ASSERT_FALSE(struct_nan.Equals(struct_nan, options)); |
| 215 | + ASSERT_FALSE(struct_nan.Equals(struct_other_nan, options)); |
| 216 | + ASSERT_FALSE(struct_val.ApproxEquals(struct_other_val, options)); |
| 217 | + ASSERT_FALSE(struct_other_val.ApproxEquals(struct_val, options)); |
| 218 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_val, options)); |
| 219 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_nan, options)); |
| 220 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_other_nan, options)); |
| 221 | + |
| 222 | + options = options.atol(0.15); |
| 223 | + ASSERT_FALSE(struct_val.Equals(struct_other_val, options)); |
| 224 | + ASSERT_FALSE(struct_other_val.Equals(struct_val, options)); |
| 225 | + ASSERT_FALSE(struct_nan.Equals(struct_val, options)); |
| 226 | + ASSERT_FALSE(struct_nan.Equals(struct_nan, options)); |
| 227 | + ASSERT_FALSE(struct_nan.Equals(struct_other_nan, options)); |
| 228 | + ASSERT_TRUE(struct_val.ApproxEquals(struct_other_val, options)); |
| 229 | + ASSERT_TRUE(struct_other_val.ApproxEquals(struct_val, options)); |
| 230 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_val, options)); |
| 231 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_nan, options)); |
| 232 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_other_nan, options)); |
| 233 | + |
| 234 | + options = options.nans_equal(true); |
| 235 | + ASSERT_FALSE(struct_val.Equals(struct_other_val, options)); |
| 236 | + ASSERT_FALSE(struct_other_val.Equals(struct_val, options)); |
| 237 | + ASSERT_FALSE(struct_nan.Equals(struct_val, options)); |
| 238 | + ASSERT_TRUE(struct_nan.Equals(struct_nan, options)); |
| 239 | + ASSERT_TRUE(struct_nan.Equals(struct_other_nan, options)); |
| 240 | + ASSERT_TRUE(struct_val.ApproxEquals(struct_other_val, options)); |
| 241 | + ASSERT_TRUE(struct_other_val.ApproxEquals(struct_val, options)); |
| 242 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_val, options)); |
| 243 | + ASSERT_TRUE(struct_nan.ApproxEquals(struct_nan, options)); |
| 244 | + ASSERT_TRUE(struct_nan.ApproxEquals(struct_other_nan, options)); |
| 245 | + |
| 246 | + options = options.atol(0.05); |
| 247 | + ASSERT_FALSE(struct_val.Equals(struct_other_val, options)); |
| 248 | + ASSERT_FALSE(struct_other_val.Equals(struct_val, options)); |
| 249 | + ASSERT_FALSE(struct_nan.Equals(struct_val, options)); |
| 250 | + ASSERT_TRUE(struct_nan.Equals(struct_nan, options)); |
| 251 | + ASSERT_TRUE(struct_nan.Equals(struct_other_nan, options)); |
| 252 | + ASSERT_FALSE(struct_val.ApproxEquals(struct_other_val, options)); |
| 253 | + ASSERT_FALSE(struct_other_val.ApproxEquals(struct_val, options)); |
| 254 | + ASSERT_FALSE(struct_nan.ApproxEquals(struct_val, options)); |
| 255 | + ASSERT_TRUE(struct_nan.ApproxEquals(struct_nan, options)); |
| 256 | + ASSERT_TRUE(struct_nan.ApproxEquals(struct_other_nan, options)); |
| 257 | + } |
| 258 | + |
| 259 | + void TestListOf() { |
| 260 | + auto ty = list(type_); |
| 261 | + |
| 262 | + ListScalar list_val(ArrayFromJSON(type_, "[0, null, 1.0]"), ty); |
| 263 | + ListScalar list_other_val(ArrayFromJSON(type_, "[0, null, 1.1]"), ty); |
| 264 | + ListScalar list_nan(ArrayFromJSON(type_, "[0, null, NaN]"), ty); |
| 265 | + ListScalar list_other_nan(ArrayFromJSON(type_, "[0, null, NaN]"), ty); |
| 266 | + |
| 267 | + EqualOptions options = EqualOptions::Defaults().atol(0.05); |
| 268 | + ASSERT_TRUE(list_val.Equals(list_val, options)); |
| 269 | + ASSERT_FALSE(list_val.Equals(list_other_val, options)); |
| 270 | + ASSERT_FALSE(list_nan.Equals(list_val, options)); |
| 271 | + ASSERT_FALSE(list_nan.Equals(list_nan, options)); |
| 272 | + ASSERT_FALSE(list_nan.Equals(list_other_nan, options)); |
| 273 | + ASSERT_TRUE(list_val.ApproxEquals(list_val, options)); |
| 274 | + ASSERT_FALSE(list_val.ApproxEquals(list_other_val, options)); |
| 275 | + ASSERT_FALSE(list_nan.ApproxEquals(list_val, options)); |
| 276 | + ASSERT_FALSE(list_nan.ApproxEquals(list_nan, options)); |
| 277 | + ASSERT_FALSE(list_nan.ApproxEquals(list_other_nan, options)); |
| 278 | + |
| 279 | + options = options.atol(0.15); |
| 280 | + ASSERT_TRUE(list_val.Equals(list_val, options)); |
| 281 | + ASSERT_FALSE(list_val.Equals(list_other_val, options)); |
| 282 | + ASSERT_FALSE(list_nan.Equals(list_val, options)); |
| 283 | + ASSERT_FALSE(list_nan.Equals(list_nan, options)); |
| 284 | + ASSERT_FALSE(list_nan.Equals(list_other_nan, options)); |
| 285 | + ASSERT_TRUE(list_val.ApproxEquals(list_val, options)); |
| 286 | + ASSERT_TRUE(list_val.ApproxEquals(list_other_val, options)); |
| 287 | + ASSERT_FALSE(list_nan.ApproxEquals(list_val, options)); |
| 288 | + ASSERT_FALSE(list_nan.ApproxEquals(list_nan, options)); |
| 289 | + ASSERT_FALSE(list_nan.ApproxEquals(list_other_nan, options)); |
| 290 | + |
| 291 | + options = options.nans_equal(true); |
| 292 | + ASSERT_TRUE(list_val.Equals(list_val, options)); |
| 293 | + ASSERT_FALSE(list_val.Equals(list_other_val, options)); |
| 294 | + ASSERT_FALSE(list_nan.Equals(list_val, options)); |
| 295 | + ASSERT_TRUE(list_nan.Equals(list_nan, options)); |
| 296 | + ASSERT_TRUE(list_nan.Equals(list_other_nan, options)); |
| 297 | + ASSERT_TRUE(list_val.ApproxEquals(list_val, options)); |
| 298 | + ASSERT_TRUE(list_val.ApproxEquals(list_other_val, options)); |
| 299 | + ASSERT_FALSE(list_nan.ApproxEquals(list_val, options)); |
| 300 | + ASSERT_TRUE(list_nan.ApproxEquals(list_nan, options)); |
| 301 | + ASSERT_TRUE(list_nan.ApproxEquals(list_other_nan, options)); |
| 302 | + |
| 303 | + options = options.atol(0.05); |
| 304 | + ASSERT_TRUE(list_val.Equals(list_val, options)); |
| 305 | + ASSERT_FALSE(list_val.Equals(list_other_val, options)); |
| 306 | + ASSERT_FALSE(list_nan.Equals(list_val, options)); |
| 307 | + ASSERT_TRUE(list_nan.Equals(list_nan, options)); |
| 308 | + ASSERT_TRUE(list_nan.Equals(list_other_nan, options)); |
| 309 | + ASSERT_TRUE(list_val.ApproxEquals(list_val, options)); |
| 310 | + ASSERT_FALSE(list_val.ApproxEquals(list_other_val, options)); |
| 311 | + ASSERT_FALSE(list_nan.ApproxEquals(list_val, options)); |
| 312 | + ASSERT_TRUE(list_nan.ApproxEquals(list_nan, options)); |
| 313 | + ASSERT_TRUE(list_nan.ApproxEquals(list_other_nan, options)); |
| 314 | + } |
| 315 | + |
| 316 | + protected: |
| 317 | + std::shared_ptr<DataType> type_; |
| 318 | + std::shared_ptr<Scalar> scalar_val_, scalar_other_, scalar_nan_, scalar_other_nan_; |
| 319 | +}; |
| 320 | + |
| 321 | +TYPED_TEST_SUITE(TestRealScalar, RealArrowTypes); |
| 322 | + |
| 323 | +TYPED_TEST(TestRealScalar, NanEquals) { this->TestNanEquals(); } |
| 324 | + |
| 325 | +TYPED_TEST(TestRealScalar, ApproxEquals) { this->TestApproxEquals(); } |
| 326 | + |
| 327 | +TYPED_TEST(TestRealScalar, StructOf) { this->TestStructOf(); } |
| 328 | + |
| 329 | +TYPED_TEST(TestRealScalar, ListOf) { this->TestListOf(); } |
| 330 | + |
130 | 331 | TEST(TestDecimal128Scalar, Basics) { |
131 | 332 | auto ty = decimal128(3, 2); |
132 | 333 | auto pi = Decimal128Scalar(Decimal128("3.14"), ty); |
|
0 commit comments