opal-activesupport 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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