Skip to content

Commit

Permalink
Drop runtime dependency on ActiveSupport due to minimum ruby requirement
Browse files Browse the repository at this point in the history
more_core_extensions/core_ext/object/blank.rb was copied from
https://github.com/rails/rails/blob/v5.0.0/activesupport/lib/active_support/core_ext/object/blank.rb

With the release of ActiveSupport v5.0.0 a minimum required_ruby_version
of '>= 2.2.2' was added.  The code for Blank has been copied here so that
we can continue to support ruby versions that don't meet that requirement.

The test was mostly copied as well, but rewritten in rspec syntax.

ActiveSupport has been added as a development dependency for ruby >= 2.2.2
to allow for testing nested hash features with HashWithIndifferentAccess
  • Loading branch information
bdunne committed Jul 6, 2016
1 parent 28b063e commit 72af99c
Show file tree
Hide file tree
Showing 8 changed files with 240 additions and 39 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ rvm:
- "2.2"
- ruby-head
- jruby-head
before_install: gem install bundler -v ">=1.12"
matrix:
allow_failures:
- rvm: ruby-head
Expand Down
3 changes: 1 addition & 2 deletions lib/more_core_extensions/core_ext/array/deletes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'more_core_extensions/core_ext/object/blank'

module MoreCoreExtensions
module ArrayDeletes
Expand Down
3 changes: 1 addition & 2 deletions lib/more_core_extensions/core_ext/hash/deletes.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
require 'active_support'
require 'active_support/core_ext/object/blank'
require 'more_core_extensions/core_ext/object/blank'

module MoreCoreExtensions
module HashDeletes
Expand Down
1 change: 1 addition & 0 deletions lib/more_core_extensions/core_ext/object.rb
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
require 'more_core_extensions/core_ext/object/blank'
require 'more_core_extensions/core_ext/object/namespace'
149 changes: 149 additions & 0 deletions lib/more_core_extensions/core_ext/object/blank.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# Copied from https://github.com/rails/rails/blob/v5.0.0/activesupport/lib/active_support/core_ext/object/blank.rb
# With the release of ActiveSupport v5.0.0 a minimum required_ruby_version of '>= 2.2.2' was added.
# This code has been copied here so that we can continue to support ruby versions that don't meet that requirement.

unless Object.respond_to?(:blank?)
class Object
# An object is blank if it's false, empty, or a whitespace string.
# For example, +false+, '', ' ', +nil+, [], and {} are all blank.
#
# This simplifies
#
# !address || address.empty?
#
# to
#
# address.blank?
#
# @return [true, false]
def blank?
respond_to?(:empty?) ? !!empty? : !self
end

# An object is present if it's not blank.
#
# @return [true, false]
def present?
!blank?
end

# Returns the receiver if it's present otherwise returns +nil+.
# <tt>object.presence</tt> is equivalent to
#
# object.present? ? object : nil
#
# For example, something like
#
# state = params[:state] if params[:state].present?
# country = params[:country] if params[:country].present?
# region = state || country || 'US'
#
# becomes
#
# region = params[:state].presence || params[:country].presence || 'US'
#
# @return [Object]
def presence
self if present?
end
end

class NilClass
# +nil+ is blank:
#
# nil.blank? # => true
#
# @return [true]
def blank?
true
end
end

class FalseClass
# +false+ is blank:
#
# false.blank? # => true
#
# @return [true]
def blank?
true
end
end

class TrueClass
# +true+ is not blank:
#
# true.blank? # => false
#
# @return [false]
def blank?
false
end
end

class Array
# An array is blank if it's empty:
#
# [].blank? # => true
# [1,2,3].blank? # => false
#
# @return [true, false]
alias_method :blank?, :empty?
end

class Hash
# A hash is blank if it's empty:
#
# {}.blank? # => true
# { key: 'value' }.blank? # => false
#
# @return [true, false]
alias_method :blank?, :empty?
end

class String
BLANK_RE = /\A[[:space:]]*\z/

# A string is blank if it's empty or contains whitespaces only:
#
# ''.blank? # => true
# ' '.blank? # => true
# "\t\n\r".blank? # => true
# ' blah '.blank? # => false
#
# Unicode whitespace is supported:
#
# "\u00a0".blank? # => true
#
# @return [true, false]
def blank?
# The regexp that matches blank strings is expensive. For the case of empty
# strings we can speed up this method (~3.5x) with an empty? call. The
# penalty for the rest of strings is marginal.
empty? || BLANK_RE === self
end
end

class Numeric #:nodoc:
# No number is blank:
#
# 1.blank? # => false
# 0.blank? # => false
#
# @return [false]
def blank?
false
end
end

class Time #:nodoc:
# No Time is blank:
#
# Time.now.blank? # => false
#
# @return [false]
def blank?
false
end
end
end
4 changes: 3 additions & 1 deletion more_core_extensions.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "rake"
spec.add_development_dependency "rspec", ">= 3.0"

spec.add_dependency "activesupport", "> 3.2"
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.2.2")
spec.add_development_dependency 'activesupport'
end
end
72 changes: 38 additions & 34 deletions spec/core_ext/hash/nested_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,39 +190,43 @@
include_examples "core_ext/hash/nested"
end

require 'active_support'
require 'active_support/core_ext/hash'
describe HashWithIndifferentAccess do
let(:hash) do
described_class.new.merge(
"a" => 1,
"b" => {},
"c" => {"c1" => 2},
"d" => {"d1" => {"d2" => {"d3" => 3}}},
"e" => Hash.new(4),
"f" => described_class.new { |h, k| h[k] = described_class.new },
nil => {nil => 7},
["h", "i"] => 8
)

# NOTE: "f" has to be initialized in that way due to a bug in
# HashWithIndifferentAccess and assigning a Hash with a default proc.
#
# 1.9.3 :001 > h1 = Hash.new
# 1.9.3 :002 > h1[:a] = Hash.new { |h, k| h[k] = Hash.new }
# 1.9.3 :003 > h1[:a].class
# => Hash
# 1.9.3 :004 > h1[:a][:b].class
# => Hash
#
# 1.9.3 :005 > require 'active_support/all'
# 1.9.3 :006 > h2 = HashWithIndifferentAccess.new
# 1.9.3 :007 > h2[:a] = Hash.new { |h, k| h[k] = Hash.new }
# 1.9.3 :008 > h2[:a].class
# => ActiveSupport::HashWithIndifferentAccess
# 1.9.3 :009 > h2[:a][:b].class
# => NilClass
begin
require 'active_support'
require 'active_support/core_ext/hash'
describe HashWithIndifferentAccess do
let(:hash) do
described_class.new.merge(
"a" => 1,
"b" => {},
"c" => {"c1" => 2},
"d" => {"d1" => {"d2" => {"d3" => 3}}},
"e" => Hash.new(4),
"f" => described_class.new { |h, k| h[k] = described_class.new },
nil => {nil => 7},
["h", "i"] => 8
)

# NOTE: "f" has to be initialized in that way due to a bug in
# HashWithIndifferentAccess and assigning a Hash with a default proc.
#
# 1.9.3 :001 > h1 = Hash.new
# 1.9.3 :002 > h1[:a] = Hash.new { |h, k| h[k] = Hash.new }
# 1.9.3 :003 > h1[:a].class
# => Hash
# 1.9.3 :004 > h1[:a][:b].class
# => Hash
#
# 1.9.3 :005 > require 'active_support/all'
# 1.9.3 :006 > h2 = HashWithIndifferentAccess.new
# 1.9.3 :007 > h2[:a] = Hash.new { |h, k| h[k] = Hash.new }
# 1.9.3 :008 > h2[:a].class
# => ActiveSupport::HashWithIndifferentAccess
# 1.9.3 :009 > h2[:a][:b].class
# => NilClass
end

include_examples "core_ext/hash/nested"
end

include_examples "core_ext/hash/nested"
rescue LoadError
# ActiveSupport v5.0.0 requires ruby '>=2.2.2', skip these tests on older rubies.
end
46 changes: 46 additions & 0 deletions spec/core_ext/object/blank_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
describe "blank" do
class EmptyTrue
def empty?
0
end
end

class EmptyFalse
def empty?
nil
end
end

BLANK = [EmptyTrue.new, nil, false, '', ' ', " \n\t \r ", ' ', "\u00a0", [], {}].freeze
PRESENT = [EmptyFalse.new, Object.new, true, 0, 1, 'a', [nil], {nil => 0}].freeze

describe "#blank?" do
context "true" do
BLANK.each { |v| it(v.inspect) { expect(v).to be_blank } }
end

context "false" do
PRESENT.each { |v| it(v.inspect) { expect(v).to_not be_blank } }
end
end

describe "#present?" do
context "true" do
PRESENT.each { |v| it(v.inspect) { expect(v).to be_present } }
end

context "false" do
BLANK.each { |v| it(v.inspect) { expect(v).to_not be_present } }
end
end

describe "#presence" do
context "object" do
PRESENT.each { |v| it(v.inspect) { expect(v.presence).to eq(v) } }
end

context "nil" do
BLANK.each { |v| it(v.inspect) { expect(v.presence).to be_nil } }
end
end
end

0 comments on commit 72af99c

Please # to comment.