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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +7 -0
  3. data/Rakefile +9 -2
  4. data/lib/opal/activesupport/version.rb +1 -1
  5. data/opal-activesupport.gemspec +1 -1
  6. data/opal/active_support/core_ext/array.rb +2 -0
  7. data/opal/active_support/core_ext/array/grouping.rb +99 -0
  8. data/opal/active_support/core_ext/array/wrap.rb +45 -0
  9. data/opal/active_support/core_ext/module.rb +2 -0
  10. data/opal/active_support/core_ext/module/delegation.rb +64 -0
  11. data/opal/active_support/core_ext/module/introspection.rb +62 -0
  12. data/test/abstract_unit.rb +46 -0
  13. data/test/core_ext/array_ext_test.rb +471 -0
  14. data/test/core_ext/blank_test.rb +24 -0
  15. data/{spec/core_ext/class/attribute_spec.rb → test/core_ext/class/attribute_test.rb} +16 -20
  16. data/test/core_ext/kernel_test.rb +124 -0
  17. data/test/core_ext/module/remove_method_test.rb +29 -0
  18. data/test/core_ext/module_test.rb +439 -0
  19. data/{spec/core_ext/numeric_spec.rb → test/core_ext/numeric_ext_test.rb} +110 -116
  20. data/test/core_ext/object_and_class_ext_test.rb +183 -0
  21. data/test/core_ext/string_ext_test.rb +628 -0
  22. data/{spec → test}/empty_bool.rb +0 -0
  23. data/{spec → test}/inflector_test_cases.rb +0 -0
  24. data/test/minitest/autorun.rb +29 -0
  25. metadata +39 -30
  26. data/spec/core_ext/array/extract_options_spec.rb +0 -49
  27. data/spec/core_ext/kernel_spec.rb +0 -9
  28. data/spec/core_ext/module/remove_method_spec.rb +0 -29
  29. data/spec/core_ext/object/blank_spec.rb +0 -40
  30. data/spec/core_ext/object/try_spec.rb +0 -102
  31. data/spec/core_ext/string_spec.rb +0 -71
  32. data/spec/spec_helper.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 87d2b460105407cc966e27d833b627f9f35922e1
4
- data.tar.gz: 5c55b9cc4c9093242d4944dcf1d414f1f5b9c6a9
3
+ metadata.gz: 0f50583cfaec84405d53bde416f3145fb999d402
4
+ data.tar.gz: 43cea084988895bc552064b795ac347e505b7475
5
5
  SHA512:
6
- metadata.gz: 95d565c00c6a4628ed6baa96cfc735525b76dae8fe3ca8eb985479c936dec6213f1105dd6831ee4bfeea45f08251f16c3c682f13df0d9f32f01031d33abc32c7
7
- data.tar.gz: 6b4f61e61dd0ef07188ea84f940dd781144dc64e5965e035be4676d33aea6c4f5c5e95a8cb77b67f6f4f7e1796ae3e93f4633331e606b1a965154a94f92cb960
6
+ metadata.gz: 714a1afc7c2c4cf6d19204b94fd4755e4481df11ee9d79cdbeeaa7d49b8798ce1149e02d557b590649cc2417314ba207c168958a1af4f08fe8a659370ac6fcd8
7
+ data.tar.gz: 73b58de9570c085e1ef0bfd01433177ac0cc16ff71f957bf5c0a3935c339c06d888c80ce64d86ddbdb3cdc3d8aa0f41725a69bbe0d966bc5cc667a6416c94a1d
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+
3
+ sudo: false
4
+
5
+ cache:
6
+ bundler: true
7
+
data/Rakefile CHANGED
@@ -1,7 +1,14 @@
1
1
  require 'bundler'
2
2
  Bundler.require
3
3
 
4
- require 'opal/rspec/rake_task'
5
- Opal::RSpec::RakeTask.new(:default)
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'
@@ -1,5 +1,5 @@
1
1
  module Opal
2
2
  module Activesupport
3
- VERSION = '0.2.0'
3
+ VERSION = '0.3.0'
4
4
  end
5
5
  end
@@ -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-rspec', '~> 0.4.0'
24
+ gem.add_development_dependency 'opal-minitest'
25
25
  gem.add_development_dependency 'rake'
26
26
  end
@@ -1 +1,3 @@
1
1
  require 'active_support/core_ext/array/extract_options'
2
+ require 'active_support/core_ext/array/wrap'
3
+ require 'active_support/core_ext/array/grouping'
@@ -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, '&nbsp;') {|group| p group}
12
+ # ["1", "2"]
13
+ # ["3", "4"]
14
+ # ["5", "&nbsp;"]
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, '&nbsp;') {|group| p group}
49
+ # ["1", "2", "3", "4"]
50
+ # ["5", "6", "7", "&nbsp;"]
51
+ # ["8", "9", "10", "&nbsp;"]
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
@@ -1 +1,3 @@
1
+ require 'active_support/core_ext/module/introspection'
1
2
  require 'active_support/core_ext/module/remove_method'
3
+ require 'active_support/core_ext/module/delegation'
@@ -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