diff --git a/lib/remocon/command/lib/interpreter_helper.rb b/lib/remocon/command/lib/interpreter_helper.rb index 05b73a3..c1378dc 100644 --- a/lib/remocon/command/lib/interpreter_helper.rb +++ b/lib/remocon/command/lib/interpreter_helper.rb @@ -2,9 +2,6 @@ module Remocon module InterpreterHelper - include Remocon::ConditionSorter - include Remocon::ParameterSorter - def cmd_opts raise NotImplementedError end @@ -25,7 +22,7 @@ def read_parameters end def parameter_hash - @parameter_hash ||= sort_parameters(read_parameters.first) + @parameter_hash ||= read_parameters.first end def read_conditions @@ -36,7 +33,7 @@ def read_conditions end def condition_array - @condition_array ||= sort_conditions(read_conditions.first) + @condition_array ||= read_conditions.first end def condition_names diff --git a/lib/remocon/command/pull_command.rb b/lib/remocon/command/pull_command.rb index 1c21aba..4646f09 100644 --- a/lib/remocon/command/pull_command.rb +++ b/lib/remocon/command/pull_command.rb @@ -30,6 +30,8 @@ def raw_parameters end include Remocon::InterpreterHelper + include Remocon::ConditionSorter + include Remocon::ParameterSorter attr_reader :config, :cmd_opts, :left diff --git a/lib/remocon/sorter/condition_sorter.rb b/lib/remocon/sorter/condition_sorter.rb index dff6816..57adfe1 100644 --- a/lib/remocon/sorter/condition_sorter.rb +++ b/lib/remocon/sorter/condition_sorter.rb @@ -2,22 +2,20 @@ module Remocon module ConditionSorter - CONDITION_KEYS = %i(name expression tagColor).freeze + CONDITION_KEYS = %w(name expression tagColor).freeze + + def comparator_of_condition_keys(left, right) + (CONDITION_KEYS.index(left) || 10_000) <=> (CONDITION_KEYS.index(right) || 10_000) + end def sort_conditions(conditions) conditions - .map(&:symbolize_keys) - .sort_by { |e| e[:name] } + .sort_by { |e| e["name"] || e[:name] } .map do |e| - arr = e.sort do |(a, _), (b, _)| - if !CONDITION_KEYS.include?(a) && !CONDITION_KEYS.include?(b) - a <=> b - else - (CONDITION_KEYS.index(a) || 10_000) <=> (CONDITION_KEYS.index(b) || 10_000) - end - end - - arr.each_with_object({}) { |(k, v), h| h[k] = v }.with_indifferent_access + e.stringify_keys + .sort { |(a, _), (b, _)| comparator_of_condition_keys(a, b) } + .each_with_object({}) { |(k, v), acc| acc[k] = v } + .with_indifferent_access end end end diff --git a/lib/remocon/sorter/parameter_sorter.rb b/lib/remocon/sorter/parameter_sorter.rb index 1bc0c8c..a2e6fe2 100644 --- a/lib/remocon/sorter/parameter_sorter.rb +++ b/lib/remocon/sorter/parameter_sorter.rb @@ -2,23 +2,39 @@ module Remocon module ParameterSorter - PARAMETER_KEYS = %i(description value file normalizer conditions options).freeze + PARAMETER_KEYS = %w(description value file normalizer conditions options).freeze + + def comparator_of_parameter_keys(left, right) + PARAMETER_KEYS.index(left) <=> PARAMETER_KEYS.index(right) + end def sort_parameters(parameters) - arr = parameters.sort.map do |k, v| - hash_arr = v.symbolize_keys.sort { |(a, _), (b, _)| PARAMETER_KEYS.index(a) <=> PARAMETER_KEYS.index(b) } - .map do |k1, v1| - { - k1 => k1.to_sym == :conditions ? sort_parameters(v1) : v1 - } + params = parameters.with_indifferent_access + + params.keys.sort.each_with_object({}) do |key, acc| + param = params[key] + + acc[key] = param + .stringify_keys + .sort { |(a, _), (b, _)| comparator_of_parameter_keys(a, b) } + .each_with_object({}) do |(inside_key, _), inside_acc| + if inside_key == "conditions" + inside_acc[inside_key] = sort_conditions_of_parameters(param[inside_key]) + else + inside_acc[inside_key] = param[inside_key] + end end + end.with_indifferent_access + end - { - k => hash_arr.each_with_object({}) { |hash, acc| acc.merge!(hash) } - } + def sort_conditions_of_parameters(conditions) + conditions.with_indifferent_access.to_a.each_with_object({}) do |(k, v), acc| + acc[k] = v.stringify_keys + .sort { |(a, _), (b, _)| comparator_of_parameter_keys(a, b) } + .each_with_object({}) do |(inside_key, _), inside_acc| + inside_acc[inside_key] = v[inside_key] + end end - - arr.each_with_object({}) { |hash, acc| acc.merge!(hash) }.with_indifferent_access end end end diff --git a/spec/remocon/sorter/parameter_sorter_spec.rb b/spec/remocon/sorter/parameter_sorter_spec.rb index c661fc8..fc7a5d5 100644 --- a/spec/remocon/sorter/parameter_sorter_spec.rb +++ b/spec/remocon/sorter/parameter_sorter_spec.rb @@ -4,6 +4,17 @@ module Remocon describe ParameterSorter do + def to_a(x) + case x + when Hash + to_a(x.to_a) + when Array + x.map { |a| to_a(a) } + else + x + end + end + let(:sorter) { Struct.new(:dummy) { include Remocon::ParameterSorter }.new } let(:target) do { @@ -51,9 +62,48 @@ module Remocon } end + context "#sort_conditions_of_parameters" do + let(:conditions) do + { + "xyz" => { + normalizer: "json", + value: "xyz value" + }, + "abc" => { + value: "abc value", + normalizer: "integer", + }, + "mute" => { + normalizer: "integer", + value: "mute value", + }, + "curry" => { + value: "curry value", + normalizer: "integer", + }, + "abc123" => { + normalizer: "integer", + value: "abc123 value", + } + } + end + + it "shouldn't sort keys" do + sorted_conditions = sorter.sort_conditions_of_parameters(conditions) + + keys = %w(xyz abc mute curry abc123) + + sorted_conditions.each_with_index do |(key, _), index| + expect(key).to eq(keys[index]) + end + end + end + context "#sort_parameters" do it "should sort" do - expect(sorter.sort_parameters(target)).to eq({ + sorted_target = sorter.sort_parameters(target) + + expect(to_a(sorted_target)).to eq(to_a({ key1: { description: "example example example", value: "value", @@ -82,11 +132,11 @@ module Remocon file: "file", normalizer: "json", conditions: { - "cond1" => { - value: "cond1 value" - }, "cond2" => { value: "cond2 value" + }, + "cond1" => { + value: "cond1 value" } }, options: { @@ -96,7 +146,7 @@ module Remocon } } - }.deep_stringify_keys) + }.deep_stringify_keys)) end end end