diff --git a/lib/simple_command/errors.rb b/lib/simple_command/errors.rb index c3b2bb6..b31e957 100644 --- a/lib/simple_command/errors.rb +++ b/lib/simple_command/errors.rb @@ -24,6 +24,18 @@ def full_messages map { |attribute, message| full_message(attribute, message) } end + # Allow ActiveSupport to render errors similar to ActiveModel::Errors + def as_json(options = nil) + Hash.new.tap do |output| + raise NotImplementedError.new unless output.respond_to?(:as_json) + + self.each do |field, value| + output[field] ||= [] + output[field] << value + end + end.as_json(options) + end + private def full_message(attribute, message) return message if attribute == :base diff --git a/spec/simple_command/errors_spec.rb b/spec/simple_command/errors_spec.rb index adbb2a8..7b0c3ea 100644 --- a/spec/simple_command/errors_spec.rb +++ b/spec/simple_command/errors_spec.rb @@ -78,7 +78,51 @@ it "returrns the full messages array" do expect(errors.full_messages).to eq ["Attr1 has an error", "Attr2 has an error", "Attr2 has two errors"] end + end + + describe "#as_json" do + it "raises a NotImplementedError" do + expect { errors.as_json }.to raise_error SimpleCommand::NotImplementedError + end + context "when Hash supports as_json" do + module HashAsJsonMixin + # Mock example of as_json from ActiveSupport + def as_json(options) + JSON.parse(to_json(options)) + end + end + + around do |example| + inject_required = !Hash.new.respond_to?(:as_json) + Hash.include HashAsJsonMixin if inject_required + example.run + Hash.undef_method(:as_json) if inject_required + end + + it "groups errors by key values" do + errors.add :attr1, 'has an error' + errors.add :attr2, 'has an error' + errors.add :attr2, 'has two errors' + + expect(errors.as_json).to eq( + "attr1" => ["has an error"], + "attr2" => ["has an error", "has two errors"] + ) + end + end end + describe "#to_json" do + it "groups errors by key values" do + errors.add :attr1, 'has an error' + errors.add :attr2, 'has an error' + errors.add :attr2, 'has two errors' + + expect(JSON.parse(errors.to_json)).to eq( + "attr1" => ["has an error"], + "attr2" => ["has an error", "has two errors"] + ) + end + end end