diff --git a/lib/mongoid/criteria/queryable/extensions/numeric.rb b/lib/mongoid/criteria/queryable/extensions/numeric.rb index b7d8841fe2..e1655c8c19 100644 --- a/lib/mongoid/criteria/queryable/extensions/numeric.rb +++ b/lib/mongoid/criteria/queryable/extensions/numeric.rb @@ -33,34 +33,6 @@ def __evolve_time__ module ClassMethods - # Get the object as a numeric. - # - # @api private - # - # @example Get the object as numeric. - # Object.__numeric__("1.442") - # - # @param [ Object ] object The object to convert. - # - # @return [ Object ] The converted number. - def __numeric__(object) - str = object.to_s - raise ArgumentError if str.empty? - - # These requirements seem a bit odd, but they're explicitly specified in the tests, - # so we're obligated to keep them, for now. (This code was rewritten from a one-line - # regex, due to security concerns with a polynomial regex being used on uncontrolled - # data). - - str = str.chop if str.end_with?('.') - return 0 if str.empty? - - result = Integer(str) rescue Float(object) - - integer = result.to_i - integer == result ? integer : result - end - # Evolve the object to an integer. # # @example Evolve to integers. @@ -71,7 +43,23 @@ def __numeric__(object) # @return [ Integer ] The evolved object. def evolve(object) __evolve__(object) do |obj| - __numeric__(obj) rescue obj + str = obj.to_s + if str.empty? + nil + else + # These requirements seem a bit odd, but they're explicitly specified + # in the tests, so we're obligated to keep them, for now. + str = str.chop if str.end_with?('.') + if str.empty? + 0 + else + result = Integer(str) rescue Float(obj) + integer = result.to_i + integer == result ? integer : result + end + end + rescue + obj end end end diff --git a/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb b/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb index 4fca979182..1da51ab3fd 100644 --- a/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +++ b/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb @@ -7,12 +7,12 @@ let(:host) do Class.new do - include Mongoid::Criteria::Queryable::Extensions::Numeric::ClassMethods - end.new + extend Mongoid::Criteria::Queryable::Extensions::Numeric::ClassMethods + end end - describe "#__numeric__" do - let(:actual) { host.__numeric__(str) } + describe ".evolve" do + let(:actual) { host.evolve(str) } context "when the string is a whole number" do let(:str) { '123' } @@ -80,40 +80,40 @@ context "when the string is non-numeric" do let(:str) { 'foo' } - it "raises ArgumentError" do - expect { actual }.to raise_error(ArgumentError) + it "returns the string" do + expect(actual).to eq(str) end end context "when the string is non-numeric with leading dot" do let(:str) { '.foo' } - it "raises ArgumentError" do - expect { actual }.to raise_error(ArgumentError) + it "returns the string" do + expect(actual).to eq(str) end end context "when the string is non-numeric with trailing dot" do let(:str) { 'foo.' } - it "raises ArgumentError" do - expect { actual }.to raise_error(ArgumentError) + it "returns the string" do + expect(actual).to eq(str) end end context "when the string is non-numeric with trailing dot and zeroes" do let(:str) { 'foo.000' } - it "raises ArgumentError" do - expect { actual }.to raise_error(ArgumentError) + it "returns the string" do + expect(actual).to eq(str) end end context "when the string is empty" do let(:str) { '' } - it "raises ArgumentError" do - expect { actual }.to raise_error(ArgumentError) + it "returns the string" do + expect(actual).to eq(str) end end end