From 253307e2c33ca0790e3015f78b8f22cd89dc98a3 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sun, 5 Jul 2026 14:12:16 -0500 Subject: [PATCH] Render hash/array literals deterministically in generated specs Ruby 3.4 changed Hash#inspect's default rendering of symbol keys from the hash-rocket form (:foo=>1) to the modern shorthand (foo: 1). The method_spec.erb template relied on implicit string interpolation of a real Hash object when building the "encodes ... as json" test's params, so the literal syntax emitted into generated spec files depended on whichever Ruby version ran the generator. Since CI's scheduled update_api.yml workflow pins Ruby 3.2, automated PRs could flip-flop between hash-rocket and shorthand syntax on every run, causing spurious diffs. Add a ruby_literal helper that explicitly renders Hash/Array values as source text using the modern key: value syntax (valid since Ruby 1.9, well within our supported Ruby 2.7+ range), so generated output is identical regardless of the Ruby version used to run rake slack:web:api:update. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Daniel (dB.) Doubrovkine --- CHANGELOG.md | 1 + lib/slack/web/api/templates/method_spec.erb | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90754487..6be72e63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * [#583](https://github.com/slack-ruby/slack-ruby-client/pull/583): Not found errors raised by id_for use more specific error classes when they exist - [@eizengan](https://github.com/eizengan). * [#585](https://github.com/slack-ruby/slack-ruby-client/pull/585): Fix ci not triggering on automated api update prs - [@Copilot](https://github.com/Copilot). * [#588](https://github.com/slack-ruby/slack-ruby-client/pull/588): Fix text/markdown_text mutual exclusion in chat methods - [@dblock](https://github.com/dblock). +* [#589](https://github.com/slack-ruby/slack-ruby-client/pull/589): Fix Ruby-version-dependent hash literal syntax in generated specs - [@dblock](https://github.com/dblock). * Your contribution here. ### 3.1.0 (2025/11/15) diff --git a/lib/slack/web/api/templates/method_spec.erb b/lib/slack/web/api/templates/method_spec.erb index 3b1388d6..be5a9ea5 100644 --- a/lib/slack/web/api/templates/method_spec.erb +++ b/lib/slack/web/api/templates/method_spec.erb @@ -5,6 +5,21 @@ require 'spec_helper' RSpec.describe Slack::Web::Api::Endpoints::<%= group.gsub(".", "_").camelize %> do let(:client) { Slack::Web::Client.new } +<% + # Renders a Ruby literal as source code deterministically, regardless of the + # Ruby version used to run the generator (Hash#inspect's format for symbol + # keys changed in Ruby 3.4, which would otherwise cause spurious diffs). + ruby_literal = lambda do |val| + case val + when Hash + "{#{val.map { |k, v| "#{k}: #{ruby_literal.call(v)}" }.join(', ')}}" + when Array + "[#{val.map { |v| ruby_literal.call(v) }.join(', ')}]" + else + val.inspect + end + end +%> <% names.sort.each_with_index do |(name, data), index| %> <% next if data['mixin'] %> <% group_required_params = data['arg_groups']&.map { |grp| grp['args'].first if grp['args'].size > 1 } || [] %> @@ -59,7 +74,7 @@ RSpec.describe Slack::Web::Api::Endpoints::<%= group.gsub(".", "_").camelize %> <% end %> <% if json_params.any? %> <% example_json_params = json_params.to_h { |name| [name, {data: ['data']}] } %> -<% params = example_params.merge(example_json_params).map { |name, val| val = val.is_a?(String) ? "%q[#{val}]" : val; "#{name}: #{val}" }.join(', ') %> +<% params = example_params.merge(example_json_params).map { |name, val| val = val.is_a?(String) ? "%q[#{val}]" : ruby_literal.call(val); "#{name}: #{val}" }.join(', ') %> <% expected_params = example_params.merge(example_json_params.transform_values { |v| JSON.dump(v) }).map { |name, val| val = "%q[#{val}]"; "#{name}: #{val}" }.join(', ') %> it 'encodes <%= json_params.join(', ') %> as json' do expect(client).to receive(:post).with('<%= group %>.<%= name %>', {<%= expected_params %>})