Skip to content

Commit c222047

Browse files
authored
fix edge case with periods in keys (DataDog#2722)
1 parent ec2763a commit c222047

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

.generator/src/generator/formatter.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,16 @@ def format_data_with_schema_list(
275275
return f"[\n{parameters}]"
276276

277277

278+
def _is_valid_ruby_symbol(key):
279+
"""Check if a key can be used as a Ruby symbol without quotes."""
280+
if not key:
281+
return False
282+
# Ruby symbols can start with letter or underscore, contain alphanumeric and underscores
283+
if not (key[0].isalpha() or key[0] == '_'):
284+
return False
285+
return all(c.isalnum() or c == '_' for c in key)
286+
287+
278288
@format_data_with_schema.register(dict)
279289
def format_data_with_schema_dict(
280290
data,
@@ -318,7 +328,11 @@ def format_data_with_schema_dict(
318328
name_prefix=name_prefix,
319329
replace_values=replace_values,
320330
)
321-
parameters += f"{k}: {value}, "
331+
# Use hash rocket syntax for keys with special characters
332+
if _is_valid_ruby_symbol(k):
333+
parameters += f"{k}: {value}, "
334+
else:
335+
parameters += f'"{k}" => {value}, '
322336
if not has_properties:
323337
name = None
324338

.generator/tests/test_formatter.rb

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env ruby
2+
3+
def assert(condition, message = "Assertion failed")
4+
raise message unless condition
5+
print "."
6+
end
7+
8+
def assert_equal(expected, actual, message = nil)
9+
msg = message || "Expected #{expected.inspect}, got #{actual.inspect}"
10+
raise msg unless expected == actual
11+
print "."
12+
end
13+
14+
def assert_includes(collection, item, message = nil)
15+
msg = message || "Expected #{collection.inspect} to include #{item.inspect}"
16+
raise msg unless collection.include?(item)
17+
print "."
18+
end
19+
20+
test_cases = [
21+
['valid_key', true],
22+
['_valid_key', true],
23+
['ValidKey123', true],
24+
['key123', true],
25+
['key.with.dots', false],
26+
['123invalid', false],
27+
['.starts_with_dot', false],
28+
['', false],
29+
['key-with-dash', false],
30+
['key with space', false],
31+
['key@special', false]
32+
]
33+
34+
test_cases.each do |key, expected|
35+
begin
36+
eval("{#{key}: 'value'}")
37+
assert(expected, "Expected '#{key}' to fail but it succeeded")
38+
rescue SyntaxError
39+
assert(!expected, "Expected '#{key}' to succeed but it failed")
40+
end
41+
end
42+
43+
hash = {
44+
"ocsf.activity_name" => 'Other',
45+
"ocsf.activity_id" => '99'
46+
}
47+
48+
assert(hash.is_a?(Hash))
49+
assert_equal('Other', hash["ocsf.activity_name"])
50+
assert_equal('99', hash["ocsf.activity_id"])
51+
assert_includes(hash.inspect, '"ocsf.activity_name"=>"Other"')
52+
assert_includes(hash.inspect, '"ocsf.activity_id"=>"99"')
53+
54+
hash = {
55+
"ocsf.activity_name" => ['eventName']
56+
}
57+
58+
assert(hash.is_a?(Hash))
59+
assert_equal(['eventName'], hash["ocsf.activity_name"])
60+
assert_includes(hash.inspect, '"ocsf.activity_name"=>["eventName"]')
61+
62+
hash = {
63+
normal_key: 'value1',
64+
another_key: 'value2'
65+
}
66+
67+
assert(hash.is_a?(Hash))
68+
assert_equal('value1', hash[:normal_key])
69+
assert_equal('value2', hash[:another_key])

0 commit comments

Comments
 (0)