From 6c01660dbc7c11861fbfc36341292d553c82848b Mon Sep 17 00:00:00 2001 From: Andrey Glushkov Date: Mon, 18 Nov 2024 23:49:01 +0300 Subject: [PATCH] Allow to provide any options as strings https://github.com/aglushkov/serega/issues/161 All strings options will be converted to symbols --- CHANGELOG.md | 3 +++ lib/serega.rb | 16 ++++++++++---- spec/serega_spec.rb | 52 +++++++++++++++++++++++++++++---------------- 3 files changed, 49 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68e549d..769f305 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +- Allow to provide modifiers and serialization options as strings. Only symbols + were allowed previously. + ## [0.20.1] - 2024-02-25 - Fix issue with :if plugin used together with :batch plugin. diff --git a/lib/serega.rb b/lib/serega.rb index 42d1d39..4a18706 100644 --- a/lib/serega.rb +++ b/lib/serega.rb @@ -167,6 +167,7 @@ def call(object, opts = nil) modifiers_opts = FROZEN_EMPTY_HASH serialize_opts = nil else + opts.transform_keys!(&:to_sym) serialize_opts = opts.except(*initiate_keys) modifiers_opts = opts.slice(*initiate_keys) end @@ -296,7 +297,14 @@ module InstanceMethods # @option opts [Boolean] :validate Validates provided modifiers (Default is true) # def initialize(opts = nil) - @opts = (opts.nil? || opts.empty?) ? FROZEN_EMPTY_HASH : parse_modifiers(opts) + @opts = + if opts.nil? || opts.empty? + FROZEN_EMPTY_HASH + else + opts.transform_keys!(&:to_sym) + parse_modifiers(opts) + end + self.class::CheckInitiateParams.new(@opts).validate if opts&.fetch(:check_initiate_params) { config.check_initiate_params } @plan = self.class::SeregaPlan.call(@opts) @@ -320,10 +328,10 @@ def initialize(opts = nil) # @return [Hash] Serialization result # def call(object, opts = nil) - self.class::CheckSerializeParams.new(opts).validate if opts&.any? - opts ||= {} - opts[:context] ||= {} + opts = opts ? opts.transform_keys!(&:to_sym) : {} + self.class::CheckSerializeParams.new(opts).validate unless opts.empty? + opts[:context] ||= {} serialize(object, opts) end diff --git a/spec/serega_spec.rb b/spec/serega_spec.rb index 8bef220..6796514 100644 --- a/spec/serega_spec.rb +++ b/spec/serega_spec.rb @@ -180,62 +180,78 @@ def self.plugin_name end end - let(:opts) { {except: :except} } - let(:serializer) { serializer_class.new(**opts) } + let(:modifiers) { {except: :except} } + let(:serialize_opts) { {context: {data: "bar"}} } + + let(:serializer) { serializer_class.new(modifiers) } describe "#call" do it "returns serialized response" do - expect(serializer.call("foo", context: {data: "bar"})) - .to eq({obj: "foo", ctx: "bar"}) + expect(serializer.call("foo", serialize_opts)).to eq({obj: "foo", ctx: "bar"}) + end + + context "with string opts" do + before do + modifiers.transform_keys!(&:to_s) + serialize_opts.transform_keys!(&:to_s) + end + + it "returns correct response when options provided with string keys" do + expect(serializer.call("foo", serialize_opts)).to eq({obj: "foo", ctx: "bar"}) + end end end describe "#to_h" do it "returns serialized response same as .call method" do - expect(serializer.to_h("foo", context: {data: "bar"})) - .to eq({obj: "foo", ctx: "bar"}) + expect(serializer.to_h("foo", serialize_opts)).to eq({obj: "foo", ctx: "bar"}) end end describe "#to_json" do it "returns serialized to json response" do - expect(serializer.to_json("foo", context: {data: "bar"})) - .to eq('{"obj":"foo","ctx":"bar"}') + expect(serializer.to_json("foo", serialize_opts)).to eq('{"obj":"foo","ctx":"bar"}') end end describe "#as_json" do it "returns serialized as json response (with JSON compatible types)" do - expect(serializer.as_json("foo", context: {data: "bar"})) - .to eq({"obj" => "foo", "ctx" => "bar"}) + expect(serializer.as_json("foo", serialize_opts)).to eq({"obj" => "foo", "ctx" => "bar"}) end end describe ".call" do it "returns serialized to response" do - expect(serializer_class.call("foo", **opts, context: {data: "bar"})) - .to eq({obj: "foo", ctx: "bar"}) + expect(serializer_class.call("foo", modifiers.merge(serialize_opts))).to eq({obj: "foo", ctx: "bar"}) + end + + context "with string opts" do + before do + modifiers.transform_keys!(&:to_s) + serialize_opts.transform_keys!(&:to_s) + end + + it "returns correct response when options provided with string keys" do + expect(serializer_class.call("foo", modifiers.merge(serialize_opts))).to eq({obj: "foo", ctx: "bar"}) + end end end describe ".to_h" do it "returns serialized response same as .call method" do - expect(serializer_class.to_h("foo", **opts, context: {data: "bar"})) - .to eq({obj: "foo", ctx: "bar"}) + expect(serializer_class.to_h("foo", modifiers.merge(serialize_opts))).to eq({obj: "foo", ctx: "bar"}) end end describe ".to_json" do it "returns serialized to json response" do - expect(serializer_class.to_json("foo", **opts, context: {data: "bar"})) - .to eq('{"obj":"foo","ctx":"bar"}') + expect(serializer_class.to_json("foo", modifiers.merge(serialize_opts))).to eq('{"obj":"foo","ctx":"bar"}') end end describe ".as_json" do it "returns serialized as json response (with JSON compatible types)" do - expect(serializer_class.as_json("foo", **opts, context: {data: "bar"})) - .to eq({"obj" => "foo", "ctx" => "bar"}) + expect(serializer_class.as_json("foo", modifiers.merge(serialize_opts))).to eq({"obj" => "foo", "ctx" => "bar"}) end end end