Skip to content

Commit

Permalink
Fix full error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
stind committed Jul 30, 2020
1 parent 05d0a21 commit 2536dee
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 14 deletions.
1 change: 1 addition & 0 deletions lib/dry/validation/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Validation
include Dry::Core::Constants

DOT = "."
SPACE = " "

# Root path is used for base errors in hash representation of error messages
ROOT_PATH = [nil].freeze
Expand Down
33 changes: 19 additions & 14 deletions lib/dry/validation/messages/resolver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def call(message:, tokens:, path:, meta: EMPTY_HASH)
when Symbol
Message[->(**opts) { message(message, path: path, tokens: tokens, **opts) }, path, meta]
when String
Message[->(**opts) { [message_text(message, path, **opts), meta] }, path, meta]
Message[->(**opts) { [message_text(message, path: path, **opts), meta] }, path, meta]
when Hash
meta = message.dup
text = meta.delete(:text) { |key|
Expand All @@ -51,18 +51,6 @@ def call(message:, tokens:, path:, meta: EMPTY_HASH)
end
alias_method :[], :call

# Resolve a message
#
# @return String
#
# @api public
def message_text(message, path, locale: nil, full: false, **opts)
keys = path.to_a.compact
msg_opts = EMPTY_HASH.merge(path: keys, locale: locale || messages.default_locale)

full ? "#{messages.rule(keys.last, msg_opts) || keys.last} #{message}" : message
end

# Resolve a message
#
# @return [String]
Expand Down Expand Up @@ -90,12 +78,29 @@ def message(rule, tokens: EMPTY_HASH, locale: nil, full: false, path:)
parsed_tokens = parse_tokens(tokens)
text = template.(template.data(parsed_tokens))

[full ? "#{messages.rule(keys.last, msg_opts)} #{text}" : text, meta]
[message_text(text, path: path, locale: locale, full: full), meta]
end
# rubocop:enable Metrics/AbcSize

private

def message_text(text, path:, locale: nil, full: false)
return text unless full

key = key_text(path: path, locale: locale)

[key, text].compact.join(SPACE)
end

def key_text(path:, locale: nil)
locale ||= messages.default_locale

keys = path.to_a.compact
msg_opts = {path: keys, locale: locale}

messages.rule(keys.last, msg_opts) || keys.last
end

def parse_tokens(tokens)
Hash[
tokens.map do |key, token|
Expand Down
1 change: 1 addition & 0 deletions spec/fixtures/messages/errors.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ en:
rules:
email: "E-mail"
errors:
format: "has invalid format"
rules:
not_weekend: "this only works on weekends"
email:
Expand Down
3 changes: 3 additions & 0 deletions spec/fixtures/messages/errors.pl.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
pl:
dry_validation:
rules:
email: "E-mail"
errors:
format: "ma nieprawidłowy format"
rules:
not_weekend: "to działa tylko w weekendy"
email:
Expand Down
44 changes: 44 additions & 0 deletions spec/integration/messages/resolver_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,28 @@
Message template for :not_here under "email" was not found
STR
end

context "with full: true option" do
it "returns full message text for base rule" do
expect(resolver.message(:not_weekend, path: [nil], locale: locale, full: true))
.to eql(["this only works on weekends", {}])
end

it "returns message text with translated key name" do
expect(resolver.message(:format, path: [:email], locale: locale, full: true))
.to eql(["E-mail has invalid format", {}])
end

it "supports untranslated key names" do
expect(resolver.message(:format, path: [:non_translated_key], locale: locale, full: true))
.to eql(["non_translated_key has invalid format", {}])
end

it "returns full message text for nested rule" do
expect(resolver.message(:invalid, path: %i[address street], locale: locale, full: true))
.to eql(["street doesn't look good", {}])
end
end
end

context ":pl" do
Expand All @@ -70,6 +92,28 @@
expect(resolver.message(:invalid, path: %i[address street], locale: locale))
.to eql(["nie wygląda dobrze", {}])
end

context "with full: true option" do
it "returns full message text for base rule" do
expect(resolver.message(:not_weekend, path: [nil], locale: locale, full: true))
.to eql(["to działa tylko w weekendy", {}])
end

it "returns message text with translated key name" do
expect(resolver.message(:format, path: [:email], locale: locale, full: true))
.to eql(["E-mail ma nieprawidłowy format", {}])
end

it "supports untranslated key names" do
expect(resolver.message(:format, path: [:non_translated_key], locale: locale, full: true))
.to eql(["non_translated_key ma nieprawidłowy format", {}])
end

it "returns full message text for nested rule" do
expect(resolver.message(:invalid, path: %i[address street], locale: locale, full: true))
.to eql(["street nie wygląda dobrze", {}])
end
end
end
end

Expand Down

0 comments on commit 2536dee

Please sign in to comment.