Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion .generator/src/generator/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,16 @@ def format_data_with_schema_list(
return f"[\n{parameters}]"


def _is_valid_ruby_symbol(key):
"""Check if a key can be used as a Ruby symbol without quotes."""
if not key:
return False
# Ruby symbols can start with letter or underscore, contain alphanumeric and underscores
if not (key[0].isalpha() or key[0] == '_'):
return False
return all(c.isalnum() or c == '_' for c in key)


@format_data_with_schema.register(dict)
def format_data_with_schema_dict(
data,
Expand Down Expand Up @@ -318,7 +328,11 @@ def format_data_with_schema_dict(
name_prefix=name_prefix,
replace_values=replace_values,
)
parameters += f"{k}: {value}, "
# Use hash rocket syntax for keys with special characters
if _is_valid_ruby_symbol(k):
parameters += f"{k}: {value}, "
else:
parameters += f'"{k}" => {value}, '
if not has_properties:
name = None

Expand Down
2 changes: 2 additions & 0 deletions .generator/src/generator/templates/model.j2
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ require 'date'
require 'time'

module {{ module_name }}::{{ version|upper }}
{%- if "description" in model %}
# {{ model.description.rstrip()|replace('\n', '\n# ')|indent(2) }}
{%- endif %}
{%- if model.deprecated %}
#
# @deprecated This model is deprecated.
Expand Down
69 changes: 69 additions & 0 deletions .generator/tests/test_formatter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env ruby

def assert(condition, message = "Assertion failed")
raise message unless condition
print "."
end

def assert_equal(expected, actual, message = nil)
msg = message || "Expected #{expected.inspect}, got #{actual.inspect}"
raise msg unless expected == actual
print "."
end

def assert_includes(collection, item, message = nil)
msg = message || "Expected #{collection.inspect} to include #{item.inspect}"
raise msg unless collection.include?(item)
print "."
end

test_cases = [
['valid_key', true],
['_valid_key', true],
['ValidKey123', true],
['key123', true],
['key.with.dots', false],
['123invalid', false],
['.starts_with_dot', false],
['', false],
['key-with-dash', false],
['key with space', false],
['key@special', false]
]

test_cases.each do |key, expected|
begin
eval("{#{key}: 'value'}")
assert(expected, "Expected '#{key}' to fail but it succeeded")
rescue SyntaxError
assert(!expected, "Expected '#{key}' to succeed but it failed")
end
end

hash = {
"ocsf.activity_name" => 'Other',
"ocsf.activity_id" => '99'
}

assert(hash.is_a?(Hash))
assert_equal('Other', hash["ocsf.activity_name"])
assert_equal('99', hash["ocsf.activity_id"])
assert_includes(hash.inspect, '"ocsf.activity_name"=>"Other"')
assert_includes(hash.inspect, '"ocsf.activity_id"=>"99"')

hash = {
"ocsf.activity_name" => ['eventName']
}

assert(hash.is_a?(Hash))
assert_equal(['eventName'], hash["ocsf.activity_name"])
assert_includes(hash.inspect, '"ocsf.activity_name"=>["eventName"]')

hash = {
normal_key: 'value1',
another_key: 'value2'
}

assert(hash.is_a?(Hash))
assert_equal('value1', hash[:normal_key])
assert_equal('value2', hash[:another_key])
Loading