diff --git a/lib/groonga-client-model.rb b/lib/groonga-client-model.rb index 4e88b73..b2ae844 100644 --- a/lib/groonga-client-model.rb +++ b/lib/groonga-client-model.rb @@ -44,3 +44,7 @@ module GroongaClientModel if defined?(Rails) require "groonga_client_model/railtie" end + +ActiveSupport.on_load(:i18n) do + I18n.load_path << "#{__dir__}/groonga_client_model/locale/en.yml" +end diff --git a/lib/groonga_client_model/locale/en.yml b/lib/groonga_client_model/locale/en.yml new file mode 100644 index 0000000..fdf65fe --- /dev/null +++ b/lib/groonga_client_model/locale/en.yml @@ -0,0 +1,7 @@ +en: + errors: + messages: + uint: + "must be positive integer: %{inspected_value}" + uint32: + "must be less than 2 ** 32: %{inspected_value}" diff --git a/lib/groonga_client_model/record.rb b/lib/groonga_client_model/record.rb index 7229beb..5563c42 100644 --- a/lib/groonga_client_model/record.rb +++ b/lib/groonga_client_model/record.rb @@ -138,10 +138,13 @@ def define_method_attribute=(name) attr_reader :attributes - validates :_key, + validates(:_key, presence: true, + if: ->(record) {record.class.have_key?}) + validates(:_key, "groonga_client_model/validations/type": true, - if: ->(record) {record.class.have_key?} + if: ->(record) {record.class.have_key?}, + allow_blank: true) def initialize(attributes=nil) @attributes = {} diff --git a/lib/groonga_client_model/validations/type_validator.rb b/lib/groonga_client_model/validations/type_validator.rb index 93a86b4..30d7289 100644 --- a/lib/groonga_client_model/validations/type_validator.rb +++ b/lib/groonga_client_model/validations/type_validator.rb @@ -30,7 +30,7 @@ def validate_each(record, attribute, value) end private - def validate_uint32(record, attribute, value) + def validate_uint(record, attribute, value, n_bits) if value.is_a?(String) begin value = Integer(value) @@ -40,16 +40,28 @@ def validate_uint32(record, attribute, value) case value when Numeric - return if value >= 0 - record.errors.add(attribute, - "must be positive integer: #{value.inspect}", - options) + if value < 0 + record.errors.add(attribute, + :uint, + options.merge(inspected_value: value.inspect)) + return + end + if value > ((2 ** n_bits) - 1) + record.errors.add(attribute, + :"uint#{n_bits}", + options.merge(inspected_value: value.inspect)) + return + end else record.errors.add(attribute, - "must be positive integer: #{value.inspect}", - options) + :uint, + options.merge(inspected_value: value.inspect)) end end + + def validate_uint32(record, attribute, value) + validate_uint(record, attribute, value, 32) + end end end end diff --git a/test/unit/test_record.rb b/test/unit/test_record.rb index eac8ea6..02d1b4f 100644 --- a/test/unit/test_record.rb +++ b/test/unit/test_record.rb @@ -56,7 +56,7 @@ def columns end sub_test_case("validations") do - sub_test_case("_key presence") do + sub_test_case("_key") do class NoKey < GroongaClientModel::Record class << self def columns @@ -68,7 +68,7 @@ def columns end end - class HaveKey < GroongaClientModel::Record + class Key < GroongaClientModel::Record class << self def columns raw_columns = { @@ -76,7 +76,7 @@ def columns "_key" => Column.new(nil, { "name" => "_key", "value_type" => { - "name" => "ShortText", + "name" => key_type, }, }), } @@ -85,23 +85,99 @@ def columns end end - test "no key" do - record = NoKey.new - assert do - record.valid? + class ShortTextKey < Key + class << self + def key_type + "ShortText" + end + end + end + + class UInt32Key < Key + class << self + def key_type + "UInt32" + end end - assert_equal({}, record.errors.messages) end - test "have key" do - record = HaveKey.new - assert do - not record.save + sub_test_case("presence") do + test "no key" do + record = NoKey.new + assert do + record.valid? + end + assert_equal({}, record.errors.messages) + end + + test "missing key" do + record = ShortTextKey.new + assert do + not record.valid? + end + message = record.errors.generate_message(:_key, :blank) + assert_equal({ + :_key => [message], + }, + record.errors.messages) + end + + test "blank key" do + record = UInt32Key.new(_key: "") + assert do + not record.valid? + end + message = record.errors.generate_message(:_key, :blank) + assert_equal({ + :_key => [message], + }, + record.errors.messages) + end + + test "have key" do + record = ShortTextKey.new(_key: "String") + assert do + record.valid? + end + assert_equal({}, + record.errors.messages) + end + end + + sub_test_case("type") do + sub_test_case("UInt32") do + test("invalid") do + key = "String" + record = UInt32Key.new(_key: key) + assert do + not record.valid? + end + options = { + inspected_value: key.inspect + } + message = record.errors.generate_message(:_key, :uint, options) + assert_equal({ + :_key => [message], + }, + record.errors.messages) + end + + test("too large") do + key = 2 ** 32 + record = UInt32Key.new(_key: key) + assert do + not record.valid? + end + options = { + inspected_value: key.inspect + } + message = record.errors.generate_message(:_key, :uint32, options) + assert_equal({ + :_key => [message], + }, + record.errors.messages) + end end - assert_equal({ - :_key => [record.errors.generate_message(:_key, :blank)], - }, - record.errors.messages) end end end