diff --git a/lib/mutations/float_filter.rb b/lib/mutations/float_filter.rb index f3ef45d..a1e9d8e 100644 --- a/lib/mutations/float_filter.rb +++ b/lib/mutations/float_filter.rb @@ -1,19 +1,25 @@ module Mutations class FloatFilter < AdditionalFilter @default_options = { - :nils => false, # true allows an explicit nil to be valid. Overrides any other options - :min => nil, # lowest value, inclusive - :max => nil # highest value, inclusive + :nils => false, # true allows an explicit nil to be valid. Overrides any other options + :empty_is_nil => true, # if true, treat empty string as if it were nil + :min => nil, # lowest value, inclusive + :max => nil # highest value, inclusive } def filter(data) + # change empty to nil if required + if data == "" && options[:empty_is_nil] + data = nil + end + # Handle nil case if data.nil? return [nil, nil] if options[:nils] return [nil, :nils] end - + # Now check if it's empty: return [data, :empty] if data == "" @@ -21,7 +27,7 @@ def filter(data) if !data.is_a?(Float) if data.is_a?(String) && data =~ /^[-+]?\d*\.?\d+/ data = data.to_f - elsif data.is_a?(Integer) + elsif data.is_a?(Numeric) data = data.to_f else return [data, :float] diff --git a/lib/mutations/integer_filter.rb b/lib/mutations/integer_filter.rb index 4b88b1a..ba9a5fe 100644 --- a/lib/mutations/integer_filter.rb +++ b/lib/mutations/integer_filter.rb @@ -2,7 +2,7 @@ module Mutations class IntegerFilter < AdditionalFilter @default_options = { :nils => false, # true allows an explicit nil to be valid. Overrides any other options - :empty_is_nil => false, # if true, treat empty string as if it were nil + :empty_is_nil => true, # if true, treat empty string as if it were nil :min => nil, # lowest value, inclusive :max => nil, # highest value, inclusive :in => nil, # Can be an array like %w(3 4 5) diff --git a/lib/mutations/model_filter.rb b/lib/mutations/model_filter.rb index 5c66f6d..6f35a3b 100644 --- a/lib/mutations/model_filter.rb +++ b/lib/mutations/model_filter.rb @@ -1,10 +1,11 @@ module Mutations class ModelFilter < InputFilter @default_options = { - :nils => false, # true allows an explicit nil to be valid. Overrides any other options - :class => nil, # default is the attribute name.to_s.camelize.constantize. This overrides it with class or class.constantize - :builder => nil, # Could be a class or a string which will be constantized. If present, and a hash is passed, then we use that to construct a model - :new_records => false, # If false, unsaved AR records are not valid. Things that don't respond to new_record? are valid. true: anything is valid + :nils => false, # true allows an explicit nil to be valid. Overrides any other options + :empty_is_nil => true, # if true, treat empty string as if it were nil + :class => nil, # default is the attribute name.to_s.camelize.constantize. This overrides it with class or class.constantize + :builder => nil, # Could be a class or a string which will be constantized. If present, and a hash is passed, then we use that to construct a model + :new_records => false, # If false, unsaved AR records are not valid. Things that don't respond to new_record? are valid. true: anything is valid } def initialize(name, opts = {}) @@ -25,7 +26,7 @@ def initialize_constants! true end - + unless Mutations.cache_constants? options[:class] = options[:class].to_s.constantize if options[:class] options[:builder] = options[:builder].to_s.constantize if options[:builder] @@ -35,6 +36,10 @@ def initialize_constants! def filter(data) initialize_constants! + if data == "" && options[:empty_is_nil] + data = nil + end + # Handle nil case if data.nil? return [nil, nil] if options[:nils] diff --git a/spec/float_filter_spec.rb b/spec/float_filter_spec.rb index 0bbfd96..414a09a 100644 --- a/spec/float_filter_spec.rb +++ b/spec/float_filter_spec.rb @@ -65,13 +65,20 @@ assert_equal nil, filtered assert_equal nil, errors end - + it "considers empty strings to be empty" do f = Mutations::FloatFilter.new _filtered, errors = f.filter("") assert_equal :empty, errors end + it "it allows empty strings as nil" do + f = Mutations::FloatFilter.new(empty_is_nil: true, nils: true) + filtered, errors = f.filter("") + assert_equal nil, filtered + assert_equal nil, errors + end + it "considers low numbers invalid" do f = Mutations::FloatFilter.new(:min => 10) filtered, errors = f.filter(3) @@ -100,4 +107,12 @@ assert_equal nil, errors end + it 'allows BigDecimal as input' do + f = Mutations::FloatFilter.new + value = BigDecimal.new(5) + filtered, errors = f.filter(value) + assert_equal 5, filtered + assert_equal nil, errors + end + end diff --git a/spec/hash_filter_spec.rb b/spec/hash_filter_spec.rb index 7d69c51..a6c8c7a 100644 --- a/spec/hash_filter_spec.rb +++ b/spec/hash_filter_spec.rb @@ -155,7 +155,7 @@ assert_equal ({"foo" => "bar"}), filtered assert_equal nil, errors end - + it "bar is optional -- discards empty if it needs to be stripped" do hf = Mutations::HashFilter.new do required do @@ -170,7 +170,7 @@ assert_equal ({"foo" => "bar"}), filtered assert_equal nil, errors end - + it "bar is optional -- don't discard empty if it's spaces but stripping is off" do hf = Mutations::HashFilter.new do required do diff --git a/spec/model_filter_spec.rb b/spec/model_filter_spec.rb index 173caf9..f8bcd50 100644 --- a/spec/model_filter_spec.rb +++ b/spec/model_filter_spec.rb @@ -60,7 +60,15 @@ def new_record? assert_equal nil, filtered assert_equal nil, errors end - + + it 'treats empty as nil with the option empty' do + # This is useful for Graphql where every nil gets made into empty strings + f = Mutations::ModelFilter.new(:simple_model, nils: true, empty_is_nil: true) + filtered, errors = f.filter("") + assert_equal nil, filtered + assert_equal nil, errors + end + it "will re-constantize if cache_constants is false" do was = Mutations.cache_constants? Mutations.cache_constants = false @@ -69,16 +77,16 @@ def new_record? filtered, errors = f.filter(m) assert_equal m, filtered assert_equal nil, errors - + Object.send(:remove_const, 'SimpleModel') - + class SimpleModel; end - + m = SimpleModel.new filtered, errors = f.filter(m) assert_equal m, filtered assert_equal nil, errors - + Mutations.cache_constants = was end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 31a38b3..6d8905d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,5 +1,6 @@ require 'minitest/unit' require 'minitest/autorun' +require 'bigdecimal' require 'pp' $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__))