opal-activesupport 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +7 -0
- data/Rakefile +9 -2
- data/lib/opal/activesupport/version.rb +1 -1
- data/opal-activesupport.gemspec +1 -1
- data/opal/active_support/core_ext/array.rb +2 -0
- data/opal/active_support/core_ext/array/grouping.rb +99 -0
- data/opal/active_support/core_ext/array/wrap.rb +45 -0
- data/opal/active_support/core_ext/module.rb +2 -0
- data/opal/active_support/core_ext/module/delegation.rb +64 -0
- data/opal/active_support/core_ext/module/introspection.rb +62 -0
- data/test/abstract_unit.rb +46 -0
- data/test/core_ext/array_ext_test.rb +471 -0
- data/test/core_ext/blank_test.rb +24 -0
- data/{spec/core_ext/class/attribute_spec.rb → test/core_ext/class/attribute_test.rb} +16 -20
- data/test/core_ext/kernel_test.rb +124 -0
- data/test/core_ext/module/remove_method_test.rb +29 -0
- data/test/core_ext/module_test.rb +439 -0
- data/{spec/core_ext/numeric_spec.rb → test/core_ext/numeric_ext_test.rb} +110 -116
- data/test/core_ext/object_and_class_ext_test.rb +183 -0
- data/test/core_ext/string_ext_test.rb +628 -0
- data/{spec → test}/empty_bool.rb +0 -0
- data/{spec → test}/inflector_test_cases.rb +0 -0
- data/test/minitest/autorun.rb +29 -0
- metadata +39 -30
- data/spec/core_ext/array/extract_options_spec.rb +0 -49
- data/spec/core_ext/kernel_spec.rb +0 -9
- data/spec/core_ext/module/remove_method_spec.rb +0 -29
- data/spec/core_ext/object/blank_spec.rb +0 -40
- data/spec/core_ext/object/try_spec.rb +0 -102
- data/spec/core_ext/string_spec.rb +0 -71
- data/spec/spec_helper.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f50583cfaec84405d53bde416f3145fb999d402
|
4
|
+
data.tar.gz: 43cea084988895bc552064b795ac347e505b7475
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 714a1afc7c2c4cf6d19204b94fd4755e4481df11ee9d79cdbeeaa7d49b8798ce1149e02d557b590649cc2417314ba207c168958a1af4f08fe8a659370ac6fcd8
|
7
|
+
data.tar.gz: 73b58de9570c085e1ef0bfd01433177ac0cc16ff71f957bf5c0a3935c339c06d888c80ce64d86ddbdb3cdc3d8aa0f41725a69bbe0d966bc5cc667a6416c94a1d
|
data/.travis.yml
ADDED
data/Rakefile
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
Bundler.require
|
3
3
|
|
4
|
-
require 'opal/
|
5
|
-
Opal::
|
4
|
+
require 'opal/minitest/rake_task'
|
5
|
+
# Opal::Minitest::RakeTask.new
|
6
|
+
|
7
|
+
task :test do
|
8
|
+
files = Dir['test/**/*_test.rb'].map {|f| "-r #{f.chomp('.rb').sub(/^test\//, '')}"}
|
9
|
+
sh "bundle exec ruby -r opal/minitest -S opal -Dwarning -Itest -Iopal #{files.join(' ')} -e puts"
|
10
|
+
end
|
11
|
+
|
12
|
+
task default: :test
|
6
13
|
|
7
14
|
require 'bundler/gem_tasks'
|
data/opal-activesupport.gemspec
CHANGED
@@ -21,6 +21,6 @@ Gem::Specification.new do |gem|
|
|
21
21
|
gem.require_paths = ['lib']
|
22
22
|
|
23
23
|
gem.add_dependency 'opal', ['>= 0.5.0', '< 1.0.0']
|
24
|
-
gem.add_development_dependency 'opal-
|
24
|
+
gem.add_development_dependency 'opal-minitest'
|
25
25
|
gem.add_development_dependency 'rake'
|
26
26
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
class Array
|
2
|
+
# Splits or iterates over the array in groups of size +number+,
|
3
|
+
# padding any remaining slots with +fill_with+ unless it is +false+.
|
4
|
+
#
|
5
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups_of(3) {|group| p group}
|
6
|
+
# ["1", "2", "3"]
|
7
|
+
# ["4", "5", "6"]
|
8
|
+
# ["7", "8", "9"]
|
9
|
+
# ["10", nil, nil]
|
10
|
+
#
|
11
|
+
# %w(1 2 3 4 5).in_groups_of(2, ' ') {|group| p group}
|
12
|
+
# ["1", "2"]
|
13
|
+
# ["3", "4"]
|
14
|
+
# ["5", " "]
|
15
|
+
#
|
16
|
+
# %w(1 2 3 4 5).in_groups_of(2, false) {|group| p group}
|
17
|
+
# ["1", "2"]
|
18
|
+
# ["3", "4"]
|
19
|
+
# ["5"]
|
20
|
+
def in_groups_of(number, fill_with = nil)
|
21
|
+
if fill_with == false
|
22
|
+
collection = self
|
23
|
+
else
|
24
|
+
# size % number gives how many extra we have;
|
25
|
+
# subtracting from number gives how many to add;
|
26
|
+
# modulo number ensures we don't add group of just fill.
|
27
|
+
padding = (number - size % number) % number
|
28
|
+
collection = dup.concat([fill_with] * padding)
|
29
|
+
end
|
30
|
+
|
31
|
+
if block_given?
|
32
|
+
collection.each_slice(number) { |slice| yield(slice) }
|
33
|
+
else
|
34
|
+
groups = []
|
35
|
+
collection.each_slice(number) { |group| groups << group }
|
36
|
+
groups
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Splits or iterates over the array in +number+ of groups, padding any
|
41
|
+
# remaining slots with +fill_with+ unless it is +false+.
|
42
|
+
#
|
43
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
|
44
|
+
# ["1", "2", "3", "4"]
|
45
|
+
# ["5", "6", "7", nil]
|
46
|
+
# ["8", "9", "10", nil]
|
47
|
+
#
|
48
|
+
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
|
49
|
+
# ["1", "2", "3", "4"]
|
50
|
+
# ["5", "6", "7", " "]
|
51
|
+
# ["8", "9", "10", " "]
|
52
|
+
#
|
53
|
+
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
|
54
|
+
# ["1", "2", "3"]
|
55
|
+
# ["4", "5"]
|
56
|
+
# ["6", "7"]
|
57
|
+
def in_groups(number, fill_with = nil)
|
58
|
+
# size / number gives minor group size;
|
59
|
+
# size % number gives how many objects need extra accommodation;
|
60
|
+
# each group hold either division or division + 1 items.
|
61
|
+
division = size.div number
|
62
|
+
modulo = size % number
|
63
|
+
|
64
|
+
# create a new array avoiding dup
|
65
|
+
groups = []
|
66
|
+
start = 0
|
67
|
+
|
68
|
+
number.times do |index|
|
69
|
+
length = division + (modulo > 0 && modulo > index ? 1 : 0)
|
70
|
+
groups << last_group = slice(start, length)
|
71
|
+
last_group << fill_with if fill_with != false &&
|
72
|
+
modulo > 0 && length == division
|
73
|
+
start += length
|
74
|
+
end
|
75
|
+
|
76
|
+
if block_given?
|
77
|
+
groups.each { |g| yield(g) }
|
78
|
+
else
|
79
|
+
groups
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Divides the array into one or more subarrays based on a delimiting +value+
|
84
|
+
# or the result of an optional block.
|
85
|
+
#
|
86
|
+
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
|
87
|
+
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
|
88
|
+
def split(value = nil, &block)
|
89
|
+
inject([[]]) do |results, element|
|
90
|
+
if block && block.call(element) || value == element
|
91
|
+
results << []
|
92
|
+
else
|
93
|
+
results.last << element
|
94
|
+
end
|
95
|
+
|
96
|
+
results
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Array
|
2
|
+
# Wraps its argument in an array unless it is already an array (or array-like).
|
3
|
+
#
|
4
|
+
# Specifically:
|
5
|
+
#
|
6
|
+
# * If the argument is +nil+ an empty list is returned.
|
7
|
+
# * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
|
8
|
+
# * Otherwise, returns an array with the argument as its single element.
|
9
|
+
#
|
10
|
+
# Array.wrap(nil) # => []
|
11
|
+
# Array.wrap([1, 2, 3]) # => [1, 2, 3]
|
12
|
+
# Array.wrap(0) # => [0]
|
13
|
+
#
|
14
|
+
# This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
|
15
|
+
#
|
16
|
+
# * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
|
17
|
+
# moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
|
18
|
+
# such a +nil+ right away.
|
19
|
+
# * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
|
20
|
+
# raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
|
21
|
+
# * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
|
22
|
+
#
|
23
|
+
# The last point is particularly worth comparing for some enumerables:
|
24
|
+
#
|
25
|
+
# Array(foo: :bar) # => [[:foo, :bar]]
|
26
|
+
# Array.wrap(foo: :bar) # => [{:foo=>:bar}]
|
27
|
+
#
|
28
|
+
# There's also a related idiom that uses the splat operator:
|
29
|
+
#
|
30
|
+
# [*object]
|
31
|
+
#
|
32
|
+
# which for +nil+ returns <tt>[]</tt>, and calls to <tt>Array(object)</tt> otherwise.
|
33
|
+
#
|
34
|
+
# Thus, in this case the behavior may be different for +nil+, and the differences with
|
35
|
+
# <tt>Kernel#Array</tt> explained above apply to the rest of <tt>object</tt>s.
|
36
|
+
def self.wrap(object)
|
37
|
+
if object.nil?
|
38
|
+
[]
|
39
|
+
elsif object.respond_to?(:to_ary)
|
40
|
+
object.to_ary || [object]
|
41
|
+
else
|
42
|
+
[object]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
class Module
|
2
|
+
class DelegationError < NoMethodError;
|
3
|
+
end
|
4
|
+
|
5
|
+
def delegate(*methods)
|
6
|
+
options = methods.pop
|
7
|
+
unless options.is_a?(Hash) && to = options[:to]
|
8
|
+
raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
|
9
|
+
end
|
10
|
+
|
11
|
+
prefix, allow_nil = options.values_at(:prefix, :allow_nil)
|
12
|
+
|
13
|
+
if prefix == true && to =~ /^[^a-z_]/
|
14
|
+
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
15
|
+
end
|
16
|
+
|
17
|
+
method_prefix = if prefix
|
18
|
+
"#{prefix == true ? to : prefix}_"
|
19
|
+
else
|
20
|
+
''
|
21
|
+
end
|
22
|
+
|
23
|
+
to = to.to_s
|
24
|
+
|
25
|
+
methods.each do |method|
|
26
|
+
# Attribute writer methods only accept one argument. Makes sure []=
|
27
|
+
# methods still accept two arguments.
|
28
|
+
has_block = (method =~ /[^\]]=$/) ? false : true
|
29
|
+
method_name = method_prefix + method
|
30
|
+
# Avoiding the eval approach rails/active_support takes since it was brittle with making this work
|
31
|
+
resolve_to = lambda do |scope|
|
32
|
+
if to.start_with?('@')
|
33
|
+
ivar_name = to[1..-1]
|
34
|
+
# Had problems with instance_variable_get
|
35
|
+
`#{scope}[#{ivar_name}]`
|
36
|
+
else
|
37
|
+
scope.__send__(to)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
exception = lambda do |scope|
|
41
|
+
DelegationError.new("#{scope}#{method_name} delegated to #{to}.#{method} but #{to} is nil: #{scope.inspect}", method_name)
|
42
|
+
end
|
43
|
+
if has_block
|
44
|
+
define_method(method_name) do |*args, &block|
|
45
|
+
to_resolved = resolve_to[self]
|
46
|
+
unless to_resolved
|
47
|
+
next if allow_nil
|
48
|
+
raise exception[self]
|
49
|
+
end
|
50
|
+
to_resolved.__send__(method, *args, &block)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
define_method(method_name) do |arg|
|
54
|
+
to_resolved = resolve_to[self]
|
55
|
+
unless to_resolved
|
56
|
+
next if allow_nil
|
57
|
+
raise exception[self]
|
58
|
+
end
|
59
|
+
to_resolved.__send__(method, arg)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'active_support/inflector'
|
2
|
+
|
3
|
+
class Module
|
4
|
+
# Returns the name of the module containing this one.
|
5
|
+
#
|
6
|
+
# M::N.parent_name # => "M"
|
7
|
+
def parent_name
|
8
|
+
if defined? @parent_name
|
9
|
+
@parent_name
|
10
|
+
else
|
11
|
+
@parent_name = name =~ /::[^:]+$/ ? $`.freeze : nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Returns the module which contains this one according to its name.
|
16
|
+
#
|
17
|
+
# module M
|
18
|
+
# module N
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# X = M::N
|
22
|
+
#
|
23
|
+
# M::N.parent # => M
|
24
|
+
# X.parent # => M
|
25
|
+
#
|
26
|
+
# The parent of top-level and anonymous modules is Object.
|
27
|
+
#
|
28
|
+
# M.parent # => Object
|
29
|
+
# Module.new.parent # => Object
|
30
|
+
def parent
|
31
|
+
parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns all the parents of this module according to its name, ordered from
|
35
|
+
# nested outwards. The receiver is not contained within the result.
|
36
|
+
#
|
37
|
+
# module M
|
38
|
+
# module N
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# X = M::N
|
42
|
+
#
|
43
|
+
# M.parents # => [Object]
|
44
|
+
# M::N.parents # => [M, Object]
|
45
|
+
# X.parents # => [M, Object]
|
46
|
+
def parents
|
47
|
+
parents = []
|
48
|
+
if parent_name
|
49
|
+
parts = parent_name.split('::')
|
50
|
+
until parts.empty?
|
51
|
+
parents << ActiveSupport::Inflector.constantize(parts * '::')
|
52
|
+
parts.pop
|
53
|
+
end
|
54
|
+
end
|
55
|
+
parents << Object unless parents.include? Object
|
56
|
+
parents
|
57
|
+
end
|
58
|
+
|
59
|
+
def local_constants #:nodoc:
|
60
|
+
constants(false)
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# ORIG_ARGV = ARGV.dup
|
2
|
+
#
|
3
|
+
# begin
|
4
|
+
# old, $VERBOSE = $VERBOSE, nil
|
5
|
+
# require File.expand_path('../../../load_paths', __FILE__)
|
6
|
+
# ensure
|
7
|
+
# $VERBOSE = old
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
# require 'active_support/core_ext/kernel/reporting'
|
11
|
+
# require 'active_support/core_ext/string/encoding'
|
12
|
+
#
|
13
|
+
# silence_warnings do
|
14
|
+
# Encoding.default_internal = "UTF-8"
|
15
|
+
# Encoding.default_external = "UTF-8"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# require 'active_support/testing/autorun'
|
19
|
+
# require 'empty_bool'
|
20
|
+
#
|
21
|
+
# ENV['NO_RELOAD'] = '1'
|
22
|
+
# require 'active_support'
|
23
|
+
#
|
24
|
+
# Thread.abort_on_exception = true
|
25
|
+
#
|
26
|
+
# # Show backtraces for deprecated behavior for quicker cleanup.
|
27
|
+
# ActiveSupport::Deprecation.debug = true
|
28
|
+
|
29
|
+
require 'minitest/autorun'
|
30
|
+
require 'empty_bool'
|
31
|
+
require 'active_support'
|
32
|
+
|
33
|
+
class ActiveSupport::TestCase < Minitest::Test
|
34
|
+
def self.test name, &block
|
35
|
+
define_method "test_#{name.gsub(/[\W-]+/, '_')}", &block
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_raise error, &block
|
39
|
+
block.call
|
40
|
+
assert false, "Expected to see #{error.inspect}, but no exception was raised"
|
41
|
+
rescue error
|
42
|
+
# noop
|
43
|
+
rescue => actual_error
|
44
|
+
assert false, "Expected to see #{error.inspect}, but got #{actual_error.inspect}"
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,471 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'active_support/core_ext/array'
|
3
|
+
# require 'active_support/core_ext/big_decimal'
|
4
|
+
# require 'active_support/core_ext/object/conversions'
|
5
|
+
|
6
|
+
require 'active_support/core_ext' # FIXME: pulling in all to_xml extensions
|
7
|
+
require 'active_support/hash_with_indifferent_access'
|
8
|
+
|
9
|
+
# class ArrayExtAccessTests < ActiveSupport::TestCase
|
10
|
+
# def test_from
|
11
|
+
# assert_equal %w( a b c d ), %w( a b c d ).from(0)
|
12
|
+
# assert_equal %w( c d ), %w( a b c d ).from(2)
|
13
|
+
# assert_equal %w(), %w( a b c d ).from(10)
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def test_to
|
17
|
+
# assert_equal %w( a ), %w( a b c d ).to(0)
|
18
|
+
# assert_equal %w( a b c ), %w( a b c d ).to(2)
|
19
|
+
# assert_equal %w( a b c d ), %w( a b c d ).to(10)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# def test_second_through_tenth
|
23
|
+
# array = (1..42).to_a
|
24
|
+
#
|
25
|
+
# assert_equal array[1], array.second
|
26
|
+
# assert_equal array[2], array.third
|
27
|
+
# assert_equal array[3], array.fourth
|
28
|
+
# assert_equal array[4], array.fifth
|
29
|
+
# assert_equal array[41], array.forty_two
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# class ArrayExtToParamTests < ActiveSupport::TestCase
|
34
|
+
# class ToParam < String
|
35
|
+
# def to_param
|
36
|
+
# "#{self}1"
|
37
|
+
# end
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# def test_string_array
|
41
|
+
# assert_equal '', %w().to_param
|
42
|
+
# assert_equal 'hello/world', %w(hello world).to_param
|
43
|
+
# assert_equal 'hello/10', %w(hello 10).to_param
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# def test_number_array
|
47
|
+
# assert_equal '10/20', [10, 20].to_param
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# def test_to_param_array
|
51
|
+
# assert_equal 'custom1/param1', [ToParam.new('custom'), ToParam.new('param')].to_param
|
52
|
+
# end
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# class ArrayExtToSentenceTests < ActiveSupport::TestCase
|
56
|
+
# def test_plain_array_to_sentence
|
57
|
+
# assert_equal "", [].to_sentence
|
58
|
+
# assert_equal "one", ['one'].to_sentence
|
59
|
+
# assert_equal "one and two", ['one', 'two'].to_sentence
|
60
|
+
# assert_equal "one, two, and three", ['one', 'two', 'three'].to_sentence
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
# def test_to_sentence_with_words_connector
|
64
|
+
# assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' ')
|
65
|
+
# assert_equal "one & two, and three", ['one', 'two', 'three'].to_sentence(:words_connector => ' & ')
|
66
|
+
# assert_equal "onetwo, and three", ['one', 'two', 'three'].to_sentence(:words_connector => nil)
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# def test_to_sentence_with_last_word_connector
|
70
|
+
# assert_equal "one, two, and also three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ', and also ')
|
71
|
+
# assert_equal "one, twothree", ['one', 'two', 'three'].to_sentence(:last_word_connector => nil)
|
72
|
+
# assert_equal "one, two three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ' ')
|
73
|
+
# assert_equal "one, two and three", ['one', 'two', 'three'].to_sentence(:last_word_connector => ' and ')
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# def test_two_elements
|
77
|
+
# assert_equal "one and two", ['one', 'two'].to_sentence
|
78
|
+
# assert_equal "one two", ['one', 'two'].to_sentence(:two_words_connector => ' ')
|
79
|
+
# end
|
80
|
+
#
|
81
|
+
# def test_one_element
|
82
|
+
# assert_equal "one", ['one'].to_sentence
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# def test_one_element_not_same_object
|
86
|
+
# elements = ["one"]
|
87
|
+
# assert_not_equal elements[0].object_id, elements.to_sentence.object_id
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
# def test_one_non_string_element
|
91
|
+
# assert_equal '1', [1].to_sentence
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# def test_does_not_modify_given_hash
|
95
|
+
# options = { words_connector: ' ' }
|
96
|
+
# assert_equal "one two, and three", ['one', 'two', 'three'].to_sentence(options)
|
97
|
+
# assert_equal({ words_connector: ' ' }, options)
|
98
|
+
# end
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# class ArrayExtToSTests < ActiveSupport::TestCase
|
102
|
+
# def test_to_s_db
|
103
|
+
# collection = [
|
104
|
+
# Class.new { def id() 1 end }.new,
|
105
|
+
# Class.new { def id() 2 end }.new,
|
106
|
+
# Class.new { def id() 3 end }.new
|
107
|
+
# ]
|
108
|
+
#
|
109
|
+
# assert_equal "null", [].to_s(:db)
|
110
|
+
# assert_equal "1,2,3", collection.to_s(:db)
|
111
|
+
# end
|
112
|
+
# end
|
113
|
+
|
114
|
+
class ArrayExtGroupingTests < ActiveSupport::TestCase
|
115
|
+
def setup
|
116
|
+
Fixnum.send :private, :/ # test we avoid Integer#/ (redefined by mathn)
|
117
|
+
end
|
118
|
+
|
119
|
+
def teardown
|
120
|
+
Fixnum.send :public, :/
|
121
|
+
end
|
122
|
+
|
123
|
+
def test_in_groups_of_with_perfect_fit
|
124
|
+
groups = []
|
125
|
+
('a'..'i').to_a.in_groups_of(3) do |group|
|
126
|
+
groups << group
|
127
|
+
end
|
128
|
+
|
129
|
+
assert_equal [%w(a b c), %w(d e f), %w(g h i)], groups
|
130
|
+
assert_equal [%w(a b c), %w(d e f), %w(g h i)], ('a'..'i').to_a.in_groups_of(3)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_in_groups_of_with_padding
|
134
|
+
groups = []
|
135
|
+
('a'..'g').to_a.in_groups_of(3) do |group|
|
136
|
+
groups << group
|
137
|
+
end
|
138
|
+
|
139
|
+
assert_equal [%w(a b c), %w(d e f), ['g', nil, nil]], groups
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_in_groups_of_pads_with_specified_values
|
143
|
+
groups = []
|
144
|
+
|
145
|
+
('a'..'g').to_a.in_groups_of(3, 'foo') do |group|
|
146
|
+
groups << group
|
147
|
+
end
|
148
|
+
|
149
|
+
assert_equal [%w(a b c), %w(d e f), ['g', 'foo', 'foo']], groups
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_in_groups_of_without_padding
|
153
|
+
groups = []
|
154
|
+
|
155
|
+
('a'..'g').to_a.in_groups_of(3, false) do |group|
|
156
|
+
groups << group
|
157
|
+
end
|
158
|
+
|
159
|
+
assert_equal [%w(a b c), %w(d e f), ['g']], groups
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_in_groups_returned_array_size
|
163
|
+
array = (1..7).to_a
|
164
|
+
|
165
|
+
1.upto(array.size + 1) do |number|
|
166
|
+
assert_equal number, array.in_groups(number).size
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_in_groups_with_empty_array
|
171
|
+
assert_equal [[], [], []], [].in_groups(3)
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_in_groups_with_block
|
175
|
+
array = (1..9).to_a
|
176
|
+
groups = []
|
177
|
+
|
178
|
+
array.in_groups(3) do |group|
|
179
|
+
groups << group
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_equal array.in_groups(3), groups
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_in_groups_with_perfect_fit
|
186
|
+
assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]],
|
187
|
+
(1..9).to_a.in_groups(3)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_in_groups_with_padding
|
191
|
+
array = (1..7).to_a
|
192
|
+
|
193
|
+
assert_equal [[1, 2, 3], [4, 5, nil], [6, 7, nil]],
|
194
|
+
array.in_groups(3)
|
195
|
+
assert_equal [[1, 2, 3], [4, 5, 'foo'], [6, 7, 'foo']],
|
196
|
+
array.in_groups(3, 'foo')
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_in_groups_without_padding
|
200
|
+
assert_equal [[1, 2, 3], [4, 5], [6, 7]],
|
201
|
+
(1..7).to_a.in_groups(3, false)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class ArraySplitTests < ActiveSupport::TestCase
|
206
|
+
def test_split_with_empty_array
|
207
|
+
assert_equal [[]], [].split(0)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_split_with_argument
|
211
|
+
assert_equal [[1, 2], [4, 5]], [1, 2, 3, 4, 5].split(3)
|
212
|
+
assert_equal [[1, 2, 3, 4, 5]], [1, 2, 3, 4, 5].split(0)
|
213
|
+
end
|
214
|
+
|
215
|
+
def test_split_with_block
|
216
|
+
assert_equal [[1, 2], [4, 5], [7, 8], [10]], (1..10).to_a.split { |i| i % 3 == 0 }
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_split_with_edge_values
|
220
|
+
assert_equal [[], [2, 3, 4, 5]], [1, 2, 3, 4, 5].split(1)
|
221
|
+
assert_equal [[1, 2, 3, 4], []], [1, 2, 3, 4, 5].split(5)
|
222
|
+
assert_equal [[], [2, 3, 4], []], [1, 2, 3, 4, 5].split { |i| i == 1 || i == 5 }
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# class ArrayToXmlTests < ActiveSupport::TestCase
|
227
|
+
# def test_to_xml
|
228
|
+
# xml = [
|
229
|
+
# { :name => "David", :age => 26, :age_in_millis => 820497600000 },
|
230
|
+
# { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
|
231
|
+
# ].to_xml(:skip_instruct => true, :indent => 0)
|
232
|
+
#
|
233
|
+
# assert_equal '<objects type="array"><object>', xml.first(30)
|
234
|
+
# assert xml.include?(%(<age type="integer">26</age>)), xml
|
235
|
+
# assert xml.include?(%(<age-in-millis type="integer">820497600000</age-in-millis>)), xml
|
236
|
+
# assert xml.include?(%(<name>David</name>)), xml
|
237
|
+
# assert xml.include?(%(<age type="integer">31</age>)), xml
|
238
|
+
# assert xml.include?(%(<age-in-millis type="decimal">1.0</age-in-millis>)), xml
|
239
|
+
# assert xml.include?(%(<name>Jason</name>)), xml
|
240
|
+
# end
|
241
|
+
#
|
242
|
+
# def test_to_xml_with_dedicated_name
|
243
|
+
# xml = [
|
244
|
+
# { :name => "David", :age => 26, :age_in_millis => 820497600000 }, { :name => "Jason", :age => 31 }
|
245
|
+
# ].to_xml(:skip_instruct => true, :indent => 0, :root => "people")
|
246
|
+
#
|
247
|
+
# assert_equal '<people type="array"><person>', xml.first(29)
|
248
|
+
# end
|
249
|
+
#
|
250
|
+
# def test_to_xml_with_options
|
251
|
+
# xml = [
|
252
|
+
# { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
|
253
|
+
# ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0)
|
254
|
+
#
|
255
|
+
# assert_equal "<objects><object>", xml.first(17)
|
256
|
+
# assert xml.include?(%(<street-address>Paulina</street-address>))
|
257
|
+
# assert xml.include?(%(<name>David</name>))
|
258
|
+
# assert xml.include?(%(<street-address>Evergreen</street-address>))
|
259
|
+
# assert xml.include?(%(<name>Jason</name>))
|
260
|
+
# end
|
261
|
+
#
|
262
|
+
# def test_to_xml_with_dasherize_false
|
263
|
+
# xml = [
|
264
|
+
# { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
|
265
|
+
# ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0, :dasherize => false)
|
266
|
+
#
|
267
|
+
# assert_equal "<objects><object>", xml.first(17)
|
268
|
+
# assert xml.include?(%(<street_address>Paulina</street_address>))
|
269
|
+
# assert xml.include?(%(<street_address>Evergreen</street_address>))
|
270
|
+
# end
|
271
|
+
#
|
272
|
+
# def test_to_xml_with_dasherize_true
|
273
|
+
# xml = [
|
274
|
+
# { :name => "David", :street_address => "Paulina" }, { :name => "Jason", :street_address => "Evergreen" }
|
275
|
+
# ].to_xml(:skip_instruct => true, :skip_types => true, :indent => 0, :dasherize => true)
|
276
|
+
#
|
277
|
+
# assert_equal "<objects><object>", xml.first(17)
|
278
|
+
# assert xml.include?(%(<street-address>Paulina</street-address>))
|
279
|
+
# assert xml.include?(%(<street-address>Evergreen</street-address>))
|
280
|
+
# end
|
281
|
+
#
|
282
|
+
# def test_to_with_instruct
|
283
|
+
# xml = [
|
284
|
+
# { :name => "David", :age => 26, :age_in_millis => 820497600000 },
|
285
|
+
# { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
|
286
|
+
# ].to_xml(:skip_instruct => false, :indent => 0)
|
287
|
+
#
|
288
|
+
# assert_match(/^<\?xml [^>]*/, xml)
|
289
|
+
# assert_equal 0, xml.rindex(/<\?xml /)
|
290
|
+
# end
|
291
|
+
#
|
292
|
+
# def test_to_xml_with_block
|
293
|
+
# xml = [
|
294
|
+
# { :name => "David", :age => 26, :age_in_millis => 820497600000 },
|
295
|
+
# { :name => "Jason", :age => 31, :age_in_millis => BigDecimal.new('1.0') }
|
296
|
+
# ].to_xml(:skip_instruct => true, :indent => 0) do |builder|
|
297
|
+
# builder.count 2
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# assert xml.include?(%(<count>2</count>)), xml
|
301
|
+
# end
|
302
|
+
#
|
303
|
+
# def test_to_xml_with_empty
|
304
|
+
# xml = [].to_xml
|
305
|
+
# assert_match(/type="array"\/>/, xml)
|
306
|
+
# end
|
307
|
+
#
|
308
|
+
# def test_to_xml_dups_options
|
309
|
+
# options = {:skip_instruct => true}
|
310
|
+
# [].to_xml(options)
|
311
|
+
# # :builder, etc, shouldn't be added to options
|
312
|
+
# assert_equal({:skip_instruct => true}, options)
|
313
|
+
# end
|
314
|
+
# end
|
315
|
+
|
316
|
+
class ArrayExtractOptionsTests < ActiveSupport::TestCase
|
317
|
+
class HashSubclass < Hash
|
318
|
+
end
|
319
|
+
|
320
|
+
class ExtractableHashSubclass < Hash
|
321
|
+
def extractable_options?
|
322
|
+
true
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def test_extract_options
|
327
|
+
assert_equal({}, [].extract_options!)
|
328
|
+
assert_equal({}, [1].extract_options!)
|
329
|
+
assert_equal({:a=>:b}, [{:a=>:b}].extract_options!)
|
330
|
+
assert_equal({:a=>:b}, [1, {:a=>:b}].extract_options!)
|
331
|
+
end
|
332
|
+
|
333
|
+
def test_extract_options_doesnt_extract_hash_subclasses
|
334
|
+
hash = HashSubclass.new
|
335
|
+
hash[:foo] = 1
|
336
|
+
array = [hash]
|
337
|
+
options = array.extract_options!
|
338
|
+
assert_equal({}, options)
|
339
|
+
assert_equal [hash], array
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_extract_options_extracts_extractable_subclass
|
343
|
+
hash = ExtractableHashSubclass.new
|
344
|
+
hash[:foo] = 1
|
345
|
+
array = [hash]
|
346
|
+
options = array.extract_options!
|
347
|
+
assert_equal({:foo => 1}, options)
|
348
|
+
assert_equal [], array
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_extract_options_extracts_hwia
|
352
|
+
hash = [{:foo => 1}.with_indifferent_access]
|
353
|
+
options = hash.extract_options!
|
354
|
+
assert_equal 1, options[:foo]
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
# class ArrayUniqByTests < ActiveSupport::TestCase
|
359
|
+
# def test_uniq_by
|
360
|
+
# ActiveSupport::Deprecation.silence do
|
361
|
+
# assert_equal [1,2], [1,2,3,4].uniq_by { |i| i.odd? }
|
362
|
+
# assert_equal [1,2], [1,2,3,4].uniq_by(&:even?)
|
363
|
+
# assert_equal((-5..0).to_a, (-5..5).to_a.uniq_by{ |i| i**2 })
|
364
|
+
# end
|
365
|
+
# end
|
366
|
+
#
|
367
|
+
# def test_uniq_by!
|
368
|
+
# a = [1,2,3,4]
|
369
|
+
# ActiveSupport::Deprecation.silence do
|
370
|
+
# a.uniq_by! { |i| i.odd? }
|
371
|
+
# end
|
372
|
+
# assert_equal [1,2], a
|
373
|
+
#
|
374
|
+
# a = [1,2,3,4]
|
375
|
+
# ActiveSupport::Deprecation.silence do
|
376
|
+
# a.uniq_by! { |i| i.even? }
|
377
|
+
# end
|
378
|
+
# assert_equal [1,2], a
|
379
|
+
#
|
380
|
+
# a = (-5..5).to_a
|
381
|
+
# ActiveSupport::Deprecation.silence do
|
382
|
+
# a.uniq_by! { |i| i**2 }
|
383
|
+
# end
|
384
|
+
# assert_equal((-5..0).to_a, a)
|
385
|
+
# end
|
386
|
+
# end
|
387
|
+
|
388
|
+
class ArrayWrapperTests < ActiveSupport::TestCase
|
389
|
+
class FakeCollection
|
390
|
+
def to_ary
|
391
|
+
["foo", "bar"]
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
class Proxy
|
396
|
+
def initialize(target) @target = target end
|
397
|
+
def method_missing(*a) @target.send(*a) end
|
398
|
+
end
|
399
|
+
|
400
|
+
class DoubtfulToAry
|
401
|
+
def to_ary
|
402
|
+
:not_an_array
|
403
|
+
end
|
404
|
+
end
|
405
|
+
|
406
|
+
class NilToAry
|
407
|
+
def to_ary
|
408
|
+
nil
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
def test_array
|
413
|
+
ary = %w(foo bar)
|
414
|
+
assert_same ary, Array.wrap(ary)
|
415
|
+
end
|
416
|
+
|
417
|
+
def test_nil
|
418
|
+
assert_equal [], Array.wrap(nil)
|
419
|
+
end
|
420
|
+
|
421
|
+
def test_object
|
422
|
+
o = Object.new
|
423
|
+
assert_equal [o], Array.wrap(o)
|
424
|
+
end
|
425
|
+
|
426
|
+
def test_string
|
427
|
+
assert_equal ["foo"], Array.wrap("foo")
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_string_with_newline
|
431
|
+
assert_equal ["foo\nbar"], Array.wrap("foo\nbar")
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_object_with_to_ary
|
435
|
+
assert_equal ["foo", "bar"], Array.wrap(FakeCollection.new)
|
436
|
+
end
|
437
|
+
|
438
|
+
def test_proxy_object
|
439
|
+
p = Proxy.new(Object.new)
|
440
|
+
assert_equal [p], Array.wrap(p)
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_proxy_to_object_with_to_ary
|
444
|
+
p = Proxy.new(FakeCollection.new)
|
445
|
+
assert_equal [p], Array.wrap(p)
|
446
|
+
end
|
447
|
+
|
448
|
+
def test_struct
|
449
|
+
o = Struct.new(:foo).new(123)
|
450
|
+
assert_equal [o], Array.wrap(o)
|
451
|
+
end
|
452
|
+
|
453
|
+
def test_wrap_returns_wrapped_if_to_ary_returns_nil
|
454
|
+
o = NilToAry.new
|
455
|
+
assert_equal [o], Array.wrap(o)
|
456
|
+
end
|
457
|
+
|
458
|
+
def test_wrap_does_not_complain_if_to_ary_does_not_return_an_array
|
459
|
+
assert_equal DoubtfulToAry.new.to_ary, Array.wrap(DoubtfulToAry.new)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
# class ArrayPrependAppendTest < ActiveSupport::TestCase
|
464
|
+
# def test_append
|
465
|
+
# assert_equal [1, 2], [1].append(2)
|
466
|
+
# end
|
467
|
+
#
|
468
|
+
# def test_prepend
|
469
|
+
# assert_equal [2, 1], [1].prepend(2)
|
470
|
+
# end
|
471
|
+
# end
|