|
32 | 32 |
|
33 | 33 | namespace iceberg::avro { |
34 | 34 |
|
35 | | -// Forward declaration of functions to test |
36 | | -bool validAvroName(const std::string& name); |
37 | | - |
38 | 35 | namespace { |
39 | 36 |
|
40 | 37 | void CheckCustomLogicalType(const ::avro::NodePtr& node, const std::string& type_name) { |
@@ -62,29 +59,29 @@ void CheckIcebergFieldName(const ::avro::NodePtr& node, size_t index, |
62 | 59 |
|
63 | 60 | TEST(ValidAvroNameTest, ValidNames) { |
64 | 61 | // Valid field names should return true |
65 | | - EXPECT_TRUE(validAvroName("valid_field")); |
66 | | - EXPECT_TRUE(validAvroName("field123")); |
67 | | - EXPECT_TRUE(validAvroName("_private")); |
68 | | - EXPECT_TRUE(validAvroName("CamelCase")); |
69 | | - EXPECT_TRUE(validAvroName("field_with_underscores")); |
| 62 | + EXPECT_TRUE(ValidAvroName("valid_field")); |
| 63 | + EXPECT_TRUE(ValidAvroName("field123")); |
| 64 | + EXPECT_TRUE(ValidAvroName("_private")); |
| 65 | + EXPECT_TRUE(ValidAvroName("CamelCase")); |
| 66 | + EXPECT_TRUE(ValidAvroName("field_with_underscores")); |
70 | 67 | } |
71 | 68 |
|
72 | 69 | TEST(ValidAvroNameTest, InvalidNames) { |
73 | 70 | // Names starting with numbers should return false |
74 | | - EXPECT_FALSE(validAvroName("123field")); |
75 | | - EXPECT_FALSE(validAvroName("0value")); |
| 71 | + EXPECT_FALSE(ValidAvroName("123field")); |
| 72 | + EXPECT_FALSE(ValidAvroName("0value")); |
76 | 73 |
|
77 | 74 | // Names with special characters should return false |
78 | | - EXPECT_FALSE(validAvroName("field-name")); |
79 | | - EXPECT_FALSE(validAvroName("field.name")); |
80 | | - EXPECT_FALSE(validAvroName("field name")); |
81 | | - EXPECT_FALSE(validAvroName("field@name")); |
82 | | - EXPECT_FALSE(validAvroName("field#name")); |
| 75 | + EXPECT_FALSE(ValidAvroName("field-name")); |
| 76 | + EXPECT_FALSE(ValidAvroName("field.name")); |
| 77 | + EXPECT_FALSE(ValidAvroName("field name")); |
| 78 | + EXPECT_FALSE(ValidAvroName("field@name")); |
| 79 | + EXPECT_FALSE(ValidAvroName("field#name")); |
83 | 80 | } |
84 | 81 |
|
85 | 82 | TEST(ValidAvroNameTest, EmptyName) { |
86 | | - // Empty name should throw an exception |
87 | | - EXPECT_THROW(validAvroName(""), std::runtime_error); |
| 83 | + // Empty name should return false |
| 84 | + EXPECT_FALSE(ValidAvroName("")); |
88 | 85 | } |
89 | 86 |
|
90 | 87 | TEST(SanitizeFieldNameTest, ValidFieldNames) { |
@@ -116,7 +113,7 @@ TEST(SanitizeFieldNameTest, InvalidFieldNames) { |
116 | 113 |
|
117 | 114 | TEST(SanitizeFieldNameTest, EdgeCases) { |
118 | 115 | // Empty field name |
119 | | - EXPECT_EQ(SanitizeFieldName(""), "_x0"); |
| 116 | + EXPECT_EQ(SanitizeFieldName(""), ""); |
120 | 117 |
|
121 | 118 | // Field name with only special characters |
122 | 119 | EXPECT_EQ(SanitizeFieldName("@#$"), "_x40_x23_x24"); |
@@ -258,67 +255,58 @@ TEST(ToAvroNodeVisitorTest, StructType) { |
258 | 255 | EXPECT_EQ(node->leafAt(1)->leafAt(1)->type(), ::avro::AVRO_INT); |
259 | 256 | } |
260 | 257 |
|
261 | | -TEST(ToAvroNodeVisitorTest, StructTypeWithSanitizedFieldNames) { |
262 | | - // Test struct with field names that require sanitization |
| 258 | +TEST(ToAvroNodeVisitorTest, StructTypeWithFieldNames) { |
263 | 259 | StructType struct_type{ |
264 | 260 | {SchemaField{/*field_id=*/1, "user-name", iceberg::string(), |
265 | 261 | /*optional=*/false}, |
266 | | - SchemaField{/*field_id=*/2, "email.address", iceberg::string(), |
| 262 | + SchemaField{/*field_id=*/2, "valid_field", iceberg::string(), |
| 263 | + /*optional=*/false}, |
| 264 | + SchemaField{/*field_id=*/3, "email.address", iceberg::string(), |
| 265 | + /*optional=*/true}, |
| 266 | + SchemaField{/*field_id=*/4, "AnotherField", iceberg::int32(), |
267 | 267 | /*optional=*/true}, |
268 | | - SchemaField{/*field_id=*/3, "123field", iceberg::int32(), |
| 268 | + SchemaField{/*field_id=*/5, "123field", iceberg::int32(), |
269 | 269 | /*optional=*/false}, |
270 | | - SchemaField{/*field_id=*/4, "field with spaces", iceberg::boolean(), |
| 270 | + SchemaField{/*field_id=*/6, "field with spaces", iceberg::boolean(), |
271 | 271 | /*optional=*/true}}}; |
272 | | - |
273 | 272 | ::avro::NodePtr node; |
274 | 273 | EXPECT_THAT(ToAvroNodeVisitor{}.Visit(struct_type, &node), IsOk()); |
275 | 274 | EXPECT_EQ(node->type(), ::avro::AVRO_RECORD); |
276 | 275 |
|
277 | | - // Check that field names are sanitized |
278 | | - ASSERT_EQ(node->names(), 4); |
| 276 | + ASSERT_EQ(node->names(), 6); |
| 277 | + |
279 | 278 | EXPECT_EQ(node->nameAt(0), "user_x2Dname"); // "user-name" -> "user_x2Dname" |
280 | | - EXPECT_EQ(node->nameAt(1), |
| 279 | + EXPECT_EQ(node->nameAt(2), |
281 | 280 | "email_x2Eaddress"); // "email.address" -> "email_x2Eaddress" |
282 | | - EXPECT_EQ(node->nameAt(2), "_123field"); // "123field" -> "_123field" |
| 281 | + EXPECT_EQ(node->nameAt(4), "_123field"); // "123field" -> "_123field" |
283 | 282 | EXPECT_EQ( |
284 | | - node->nameAt(3), |
| 283 | + node->nameAt(5), |
285 | 284 | "field_x20with_x20spaces"); // "field with spaces" -> "field_x20with_x20spaces" |
286 | 285 |
|
287 | | - // Check that field IDs are correctly applied |
288 | | - // Each field has 1 custom attribute: field-id |
289 | | - ASSERT_EQ(node->customAttributes(), 4); |
| 286 | + EXPECT_EQ(node->nameAt(1), "valid_field"); |
| 287 | + EXPECT_EQ(node->nameAt(3), "AnotherField"); |
| 288 | + |
| 289 | + ASSERT_EQ(node->customAttributes(), 6); |
290 | 290 | ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/0, /*field_id=*/1)); |
291 | 291 | ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/1, /*field_id=*/2)); |
292 | 292 | ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/2, /*field_id=*/3)); |
293 | 293 | ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/3, /*field_id=*/4)); |
294 | | -} |
295 | | - |
296 | | -TEST(ToAvroNodeVisitorTest, StructTypeWithValidFieldNames) { |
297 | | - // Test struct with field names that don't require sanitization |
298 | | - StructType struct_type{{SchemaField{/*field_id=*/1, "valid_field", iceberg::string(), |
299 | | - /*optional=*/false}, |
300 | | - SchemaField{/*field_id=*/2, "AnotherField", iceberg::int32(), |
301 | | - /*optional=*/true}}}; |
302 | | - |
303 | | - ::avro::NodePtr node; |
304 | | - EXPECT_THAT(ToAvroNodeVisitor{}.Visit(struct_type, &node), IsOk()); |
305 | | - EXPECT_EQ(node->type(), ::avro::AVRO_RECORD); |
306 | | - |
307 | | - // Check that field names remain unchanged |
308 | | - ASSERT_EQ(node->names(), 2); |
309 | | - EXPECT_EQ(node->nameAt(0), "valid_field"); |
310 | | - EXPECT_EQ(node->nameAt(1), "AnotherField"); |
311 | | - |
312 | | - // Check that field IDs are correctly applied |
313 | | - ASSERT_EQ(node->customAttributes(), 2); |
314 | | - ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/0, /*field_id=*/1)); |
315 | | - ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/1, /*field_id=*/2)); |
| 294 | + ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/4, /*field_id=*/5)); |
| 295 | + ASSERT_NO_FATAL_FAILURE(CheckFieldIdAt(node, /*index=*/5, /*field_id=*/6)); |
316 | 296 |
|
317 | | - // For valid field names, there should be no iceberg-field-name attributes |
318 | | - const auto& attrs0 = node->customAttributesAt(0); |
319 | | - const auto& attrs1 = node->customAttributesAt(1); |
320 | | - EXPECT_FALSE(attrs0.getAttribute("iceberg-field-name").has_value()); |
| 297 | + const auto& attrs1 = node->customAttributesAt(1); // valid_field |
| 298 | + const auto& attrs3 = node->customAttributesAt(3); // AnotherField |
321 | 299 | EXPECT_FALSE(attrs1.getAttribute("iceberg-field-name").has_value()); |
| 300 | + EXPECT_FALSE(attrs3.getAttribute("iceberg-field-name").has_value()); |
| 301 | + |
| 302 | + ASSERT_NO_FATAL_FAILURE( |
| 303 | + CheckIcebergFieldName(node, /*index=*/0, /*original_name=*/"user-name")); |
| 304 | + ASSERT_NO_FATAL_FAILURE( |
| 305 | + CheckIcebergFieldName(node, /*index=*/2, /*original_name=*/"email.address")); |
| 306 | + ASSERT_NO_FATAL_FAILURE( |
| 307 | + CheckIcebergFieldName(node, /*index=*/4, /*original_name=*/"123field")); |
| 308 | + ASSERT_NO_FATAL_FAILURE( |
| 309 | + CheckIcebergFieldName(node, /*index=*/5, /*original_name=*/"field with spaces")); |
322 | 310 | } |
323 | 311 |
|
324 | 312 | TEST(ToAvroNodeVisitorTest, ListType) { |
|
0 commit comments