sorting 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private --list-undoc -m markdown - LICENSE.txt documentation/examples.rb
data/LICENSE.txt ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) 2012, Stefan Rusterholz <stefan.rusterholz@gmail.com>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.markdown ADDED
@@ -0,0 +1,63 @@
1
+ README
2
+ ======
3
+
4
+
5
+ Summary
6
+ -------
7
+ Helpful functionality for sorting and comparing.
8
+
9
+
10
+ Installation
11
+ ------------
12
+ `gem install sorting`
13
+
14
+
15
+ Usage
16
+ -----
17
+
18
+ Sort a list of Person objects
19
+
20
+ # Convenient
21
+ require 'sorting/convenience'
22
+ people.sort_by { |person| [asc(person.first_name), asc(person.last_name), desc(person.age)] }
23
+
24
+ # Or without patching Kernel
25
+ require 'sorting'
26
+ people.sort_by { |person|
27
+ [Sorting.asc(person.first_name), Sorting.asc(person.last_name), Sorting.desc(person.age)]
28
+ }
29
+
30
+ # Care about nil values in your data
31
+ require 'sorting/convenience'
32
+ people.sort_by { |person|
33
+ [asc(person.first_name, :nils_first), asc(person.first_name, :nils_last)]
34
+ }
35
+
36
+ # Only care about nil values in your data
37
+ [5,3,nil,9].sort_by { |x| x || Sorting::Bigger } # Sorting::Smaller is available too
38
+
39
+ # Care about expensive comparison values which may not always be needed
40
+ # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
41
+ # it might only be needed in a small number of cases.
42
+ require 'sorting/convenience'
43
+ items.sort_by { |item|
44
+ [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
45
+ }
46
+
47
+ Take a look at {file:documentation/examples.rb} for more examples.
48
+
49
+
50
+ Links
51
+ -----
52
+
53
+ * [Online API Documentation](http://rdoc.info/github/apeiros/sorting/)
54
+ * [Public Repository](https://github.com/apeiros/sorting)
55
+ * [Bug Reporting](https://github.com/apeiros/sorting/issues)
56
+ * [RubyGems Site](https://rubygems.org/gems/sorting)
57
+
58
+
59
+ License
60
+ -------
61
+
62
+ You can use this code under the {file:LICENSE.txt BSD-2-Clause License}, free of charge.
63
+ If you need a different license, please ask the author.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../rake/lib', __FILE__))
2
+ Dir.glob(File.expand_path('../rake/tasks/**/*.{rake,task,rb}', __FILE__)) do |task_file|
3
+ begin
4
+ import task_file
5
+ rescue LoadError => e
6
+ warn "Failed to load task file #{task_file}"
7
+ warn " #{e.class} #{e.message}"
8
+ warn " #{e.backtrace.first}"
9
+ end
10
+ end
data/lib/sorting.rb ADDED
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require 'sorting/ascending'
6
+ require 'sorting/bigger'
7
+ require 'sorting/descending'
8
+ require 'sorting/helpers'
9
+ require 'sorting/smaller'
10
+ require 'sorting/version'
11
+
12
+
13
+
14
+ # Sorting
15
+ # Helpful functionality for sorting and comparing.
16
+ #
17
+ # @example Convenient
18
+ # require 'sorting/convenience'
19
+ # people.sort_by { |person| [asc(person.first_name), asc(person.last_name), desc(person.age)] }
20
+ #
21
+ # @example Or without patching Kernel
22
+ # require 'sorting'
23
+ # people.sort_by { |person|
24
+ # [Sorting.asc(person.first_name), Sorting.asc(person.last_name), Sorting.desc(person.age)]
25
+ # }
26
+ #
27
+ # @example Care about nil values in your data
28
+ # require 'sorting/convenience'
29
+ # people.sort_by { |person|
30
+ # [asc(person.first_name, :nils_first), asc(person.first_name, :nils_last)]
31
+ # }
32
+ #
33
+ # @example Only care about nil values in your data
34
+ # [5,3,nil,9].sort_by { |x| x || Sorting::Bigger } # Sorting::Smaller is available too
35
+ #
36
+ # @example Care about expensive comparison values which may not always be needed
37
+ # # assume item.expensive_value takes a lot of time to compute, but since it's the second value,
38
+ # # it might only be needed in a small number of cases.
39
+ # require 'sorting/convenience'
40
+ # items.sort_by { |item|
41
+ # [asc(item.cheap_value), asc(:nils_last) { item.expensive_value }]
42
+ # }
43
+ #
44
+ module Sorting
45
+ class_eval(&Sorting::Helpers::MethodDefinitions)
46
+ module_function *Sorting::Helpers.private_instance_methods(false)
47
+ end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ module Sorting
6
+
7
+ # This class is used to implement 'asc' (ascending) sorting.
8
+ # You should not need to use this class directly.
9
+ # You can `require 'sorting/convenience'` and then use Kernel#asc,
10
+ # or you can `require 'sorting'` and then use Sorting#asc (which
11
+ # is a module_function, and hence available as Sorting::asc)
12
+ #
13
+ # @see Sorting::Helpers
14
+ # Sorting::Helpers is a module which provides you with a convenient .asc
15
+ # forwarding method
16
+ #
17
+ # @see Sorting#asc
18
+ # Sorting#asc is the common way to create a Sorting::Ascending instance
19
+ #
20
+ # @see Sorting::Descending
21
+ # Sorting::Descending is the opposite of Sorting::Ascending
22
+ #
23
+ class Ascending
24
+
25
+ # Valid values for the treat_nils parameter of Sorting::Ascending#initialize
26
+ NilsValues = [:nils_first, :nils_last, nil]
27
+
28
+ include Comparable
29
+
30
+ # How nils values are treated
31
+ #
32
+ # @see NilsValues The list with all possible values
33
+ attr_reader :treat_nils
34
+
35
+ # @overload initialize(value, treat_nils=nil)
36
+ #
37
+ # Create an ascending sorted value
38
+ #
39
+ # @param [Comparable, #<=>] value
40
+ # The value to compare.
41
+ # Any object which implements <=> (or nil if you set treat_nils).
42
+ #
43
+ # @param [nil, Symbol] treat_nils
44
+ # One of nil, :nils_first, :nils_last. With nil, a normal exception
45
+ # will be raised when compared with nil. With :nils_first, a nil will
46
+ # always be considered smaller and hence be sorted to the beginning,
47
+ # with :nils_last, a nil will always be considered bigger and hence be
48
+ # sorted to the end.
49
+ #
50
+ #
51
+ # @overload initialize(treat_nils=nil, &value)
52
+ #
53
+ # Create an ascending sorted value, where the value is lazily computed.
54
+ # This is useful for values which are expensive to compute.
55
+ #
56
+ # @param [nil, Symbol] treat_nils
57
+ # One of nil, :nils_first, :nils_last. With nil, a normal exception
58
+ # will be raised when compared with nil. With :nils_first, a nil will
59
+ # always be considered smaller and hence be sorted to the beginning,
60
+ # with :nils_last, a nil will always be considered bigger and hence be
61
+ # sorted to the end.
62
+ #
63
+ # @yieldreturn [Comparable, #<=>]
64
+ # The value to compare.
65
+ # Any object which implements <=> (or nil if you set treat_nils).
66
+ #
67
+ def initialize(*args, &lazy)
68
+ @memoized = lazy ? false : true
69
+ @value = lazy || args.first
70
+ @treat_nils = args[lazy ? 0 : 1]
71
+
72
+ unless NilsValues.include?(@treat_nils)
73
+ raise ArgumentError, "Invalid value for nils, expected :nils_first or :nils_last, got #{@treat_nils.inspect}"
74
+ end
75
+ if lazy
76
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 0..1" unless args.size.between?(0, 1)
77
+ else
78
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 1..2" unless args.size.between?(1, 2)
79
+ end
80
+ end
81
+
82
+ # Whether nils are always considered smaller.
83
+ def nils_first?
84
+ @treat_nils == :nils_first
85
+ end
86
+
87
+ # Whether nils are always considered bigger.
88
+ def nils_last?
89
+ @treat_nils == :nils_last
90
+ end
91
+
92
+ # @return [Comparable, #<=>, nil]
93
+ # The comparable value. If the Ascending object was constructed with a
94
+ # lazy block, the block will be executed the first time this method is
95
+ # called.
96
+ #
97
+ def value
98
+ if @memoized
99
+ @value
100
+ else
101
+ @memoized = true
102
+ @value = @value.call
103
+ end
104
+ end
105
+
106
+ # @return [-1, 0, 1, nil]
107
+ # Comparison. Returns -1, 0, or +1 depending on whether `other` is less
108
+ # than, equal to, or greater than `self`.
109
+ # Comparison with nil is special cased when #treat_nils is set.
110
+ # If #treat_nils is :nils_first, it will always return 1, if it is
111
+ # :nils_last, it will always return -1.
112
+ # Returns nil when the value could not be compared to with `other`.
113
+ #
114
+ def <=>(other)
115
+ my_value = value
116
+
117
+ if @treat_nils && my_value.nil?
118
+ @treat_nils == :nils_first ? -1 : 1
119
+ else
120
+ other_value = other.value
121
+
122
+ if @treat_nils && other_value.nil?
123
+ @treat_nils == :nils_first ? 1 : -1
124
+ else
125
+ my_value <=> other_value
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ module Sorting
6
+
7
+ # A value whose #<=> method will always compare as being the bigger value.
8
+ # Useful for defaultizing potentially nil values before comparing/sorting.
9
+ #
10
+ # @example
11
+ # age = person.age || Sorting::Bigger
12
+ #
13
+ # @see Sorting::Smaller
14
+ #
15
+ module Bigger
16
+ extend Comparable
17
+
18
+ # @return [1]
19
+ # Comparison. Pretends this object is bigger and hence always returns 1
20
+ #
21
+ def self.<=>(other)
22
+ 1
23
+ end
24
+
25
+ # @private
26
+ # @see Numeric#coerce
27
+ #
28
+ def self.coerce(other)
29
+ [Smaller, self]
30
+ end
31
+
32
+ # @private
33
+ # @note
34
+ # Rails' ActiveSupport patches DateTime incorrectly (doesn't use coerce).
35
+ # This is a workaround
36
+ #
37
+ def self.to_datetime
38
+ self
39
+ end
40
+
41
+ # @private
42
+ # Enables comparisons with arrays
43
+ #
44
+ def self.to_ary
45
+ [self]
46
+ end
47
+
48
+ # @private
49
+ # @todo
50
+ # (SR) Figure out why this ended up here. I (SR) think it was due to
51
+ # some comparison failing without it, but I don't remember which.
52
+ # The specific case should be documented.
53
+ #
54
+ def self.to_str
55
+ self
56
+ end
57
+
58
+ # @private
59
+ # @see Object#inspect
60
+ #
61
+ def self.inspect
62
+ "#<Sorting::Bigger>"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ # The sorting/convenience.rb file adds Kernel#asc and Kernel#desc for
4
+ # convenience. The methods are defined as module functions (see
5
+ # Module#module_function), and hence also available as Kernel.asc and
6
+ # Kernel.desc
7
+
8
+
9
+
10
+ require 'sorting'
11
+
12
+
13
+
14
+ # @private
15
+ module Kernel
16
+ class_eval(&Sorting::Helpers::MethodDefinitions)
17
+ module_function *Sorting::Helpers.private_instance_methods(false)
18
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require 'sorting/ascending'
6
+
7
+
8
+
9
+ module Sorting
10
+
11
+ # This class is used to implement 'desc' (descending) sorting.
12
+ # You should not need to use this class directly.
13
+ # You can `require 'sorting/convenience'` and then use Kernel#desc,
14
+ # or you can `require 'sorting'` and then use Sorting#desc (which
15
+ # is a module_function, and hence available as Sorting::desc)
16
+ #
17
+ # @see Sorting::Helpers
18
+ # Sorting::Helpers is a module which provides you with a convenient .desc
19
+ # forwarding method
20
+ #
21
+ # @see Sorting#desc
22
+ # Sorting#desc is the common way to create a Sorting::Ascending instance
23
+ #
24
+ # @see Sorting::Descending
25
+ # Sorting::Descending is the opposite of Sorting::Ascending
26
+ #
27
+ class Descending < Ascending
28
+
29
+ # @return [-1, 0, 1, nil]
30
+ # Works reversed to how <=> works normally, i.e. it returns -1 when normal
31
+ # <=> would return 1, and vice versa.
32
+ # Comparison. Returns -1, 0, or +1 depending on whether `other` is greater
33
+ # than, equal to, or less than `self`.
34
+ # Comparison with nil is special cased when #treat_nils is set.
35
+ # If #treat_nils is :nils_first, it will always return 1, if it is
36
+ # :nils_last, it will always return -1.
37
+ # Returns nil when the value could not be compared to with `other`.
38
+ #
39
+ def <=>(other)
40
+ my_value = value
41
+
42
+ if @treat_nils && my_value.nil?
43
+ @treat_nils == :nils_first ? -1 : 1
44
+ else
45
+ other_value = other.value
46
+
47
+ if @treat_nils && other_value.nil?
48
+ @treat_nils == :nils_first ? 1 : -1
49
+ else
50
+ other_value <=> my_value
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ require 'sorting/ascending'
6
+ require 'sorting/descending'
7
+
8
+
9
+
10
+ module Sorting
11
+
12
+ # This module provides convenience methods to create Sorting::Ascending and
13
+ # Sorting::Descending instances.
14
+ module Helpers
15
+
16
+ # The proc with the method definitions of asc and desc.
17
+ # They are in a proc so the proc can be class_eval'ed in Sorting and Kernel
18
+ # to avoid an issue with methods of modules which are included in another
19
+ # module not being properly shared
20
+ #
21
+ MethodDefinitions = proc {
22
+
23
+ # Convenience method to create a Sorting::Ascending instance.
24
+ # Works exactly the same as {Sorting::Ascending#initialize}
25
+ def asc(*args, &lazy)
26
+ Sorting::Ascending.new(*args, &lazy)
27
+ end
28
+ private :asc
29
+
30
+ # Convenience method to create a Sorting::Descending instance.
31
+ # Works exactly the same as {Sorting::Ascending#initialize Descending#initialize}
32
+ def desc(*args, &lazy)
33
+ Sorting::Descending.new(*args, &lazy)
34
+ end
35
+ private :desc
36
+ }
37
+
38
+ class_eval(&MethodDefinitions)
39
+ end
40
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+
4
+
5
+ module Sorting
6
+
7
+ # A value whose #<=> method will always compare as being the smaller value.
8
+ # Useful for defaultizing potentially nil values before comparing/sorting.
9
+ #
10
+ # @example
11
+ # age = person.age || Sorting::Smaller
12
+ #
13
+ # @see Sorting::Bigger
14
+ #
15
+ module Smaller
16
+ extend Comparable
17
+
18
+ # @return [-1]
19
+ # Comparison. Pretends this object is smaller and hence always returns -1
20
+ #
21
+ def self.<=>(other)
22
+ -1
23
+ end
24
+
25
+ # @private
26
+ # @see Numeric#coerce
27
+ #
28
+ def self.coerce(other)
29
+ [Bigger, self]
30
+ end
31
+
32
+ # @private
33
+ # @note
34
+ # Rails' ActiveSupport patches DateTime incorrectly (doesn't use coerce).
35
+ # This is a workaround
36
+ #
37
+ def self.to_datetime
38
+ self
39
+ end
40
+
41
+ # @private
42
+ # @todo
43
+ # (SR) Figure out why this ended up here. I (SR) think it was due to
44
+ # some comparison failing without it, but I don't remember which.
45
+ # The specific case should be documented.
46
+ #
47
+ def self.to_str
48
+ self
49
+ end
50
+
51
+ # @private
52
+ # Enables comparisons with arrays
53
+ #
54
+ def self.to_ary
55
+ [self]
56
+ end
57
+
58
+ # @private
59
+ # @see Object#inspect
60
+ #
61
+ def self.inspect
62
+ "#<Sorting::Smaller>"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require 'rubygems/version' # newer rubygems use this
5
+ rescue LoadError
6
+ require 'gem/version' # older rubygems use this
7
+ end
8
+
9
+ module Sorting
10
+
11
+ # The version of the sorting gem.
12
+ Version = Gem::Version.new("0.0.1")
13
+ end
data/sorting.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "sorting"
5
+ s.version = "0.0.1"
6
+ s.authors = "Stefan Rusterholz"
7
+ s.email = "stefan.rusterholz@gmail.com"
8
+ s.homepage = "https://github.com/apeiros/sorting"
9
+
10
+ s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
11
+ Helpful functionality for sorting and comparing.
12
+ DESCRIPTION
13
+ s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
14
+ Helpful functionality for sorting and comparing.
15
+ SUMMARY
16
+
17
+ s.files =
18
+ Dir['bin/**/*'] +
19
+ Dir['lib/**/*'] +
20
+ Dir['rake/**/*'] +
21
+ Dir['test/**/*'] +
22
+ Dir['*.gemspec'] +
23
+ %w[
24
+ .yardopts
25
+ LICENSE.txt
26
+ Rakefile
27
+ README.markdown
28
+ ]
29
+ s.require_paths = %w[lib]
30
+ if File.directory?('bin') then
31
+ executables = Dir.chdir('bin') { Dir.glob('**/*').select { |f| File.executable?(f) } }
32
+ s.executables = executables unless executables.empty?
33
+ end
34
+
35
+ s.required_ruby_version = ">= 1.9.2"
36
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
37
+ s.rubygems_version = "1.3.1"
38
+ s.specification_version = 3
39
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Test::Unit::Assertions
4
+ # Add your custom assertions here
5
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'stringio'
4
+ require 'yaml'
5
+ require 'test/unit/assertions'
6
+ require 'sorting_test/assertions'
7
+
8
+
9
+ PROJECT_DIR = File.expand_path('../../../../', __FILE__)
10
+ TEST_DIR = File.join(PROJECT_DIR, 'test')
11
+
12
+ module TestSuite
13
+ attr_accessor :name
14
+ end
15
+
16
+ module Kernel
17
+ def suite(name, &block)
18
+ klass = Class.new(Test::Unit::TestCase)
19
+ klass.extend TestSuite
20
+ klass.name = "Suite #{name}"
21
+ klass.class_eval(&block)
22
+
23
+ klass
24
+ end
25
+ module_function :suite
26
+ end
27
+
28
+ class Test::Unit::TestCase
29
+ def self.suite(name, &block)
30
+ klass = Class.new(Test::Unit::TestCase)
31
+ klass.extend TestSuite
32
+ klass.name = "#{self.name} #{name}"
33
+ klass.class_eval(&block)
34
+
35
+ klass
36
+ end
37
+
38
+ def self.test(desc, &impl)
39
+ define_method("test #{desc}", &impl)
40
+ end
41
+
42
+ def capture_stdout
43
+ captured = StringIO.new
44
+ $stdout = captured
45
+ yield
46
+ captured.string
47
+ ensure
48
+ $stdout = STDOUT
49
+ end
50
+ end
data/test/runner.rb ADDED
@@ -0,0 +1,19 @@
1
+ # run with `ruby test/runner.rb`
2
+ # if you only want to run a single test-file: `ruby test/runner.rb testfile.rb`
3
+
4
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH << File.expand_path('../../test/lib', __FILE__)
6
+
7
+ require 'test/unit'
8
+ require 'sorting_test/helper'
9
+
10
+ if ENV['COVERAGE']
11
+ require 'simplecov'
12
+ SimpleCov.start
13
+ end
14
+
15
+ units = ARGV.empty? ? Dir["#{TEST_DIR}/unit/**/*.rb"] : ARGV
16
+
17
+ units.each do |unit|
18
+ load unit
19
+ end
@@ -0,0 +1,118 @@
1
+ # encoding: utf-8
2
+
3
+ require 'sorting/convenience'
4
+
5
+ suite "Sorting" do
6
+ suite "Ascending" do
7
+ test "#initialize" do
8
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(0)
9
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(0, nil)
10
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(0, :nils_first)
11
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(0, :nils_last)
12
+ assert_raises ArgumentError do Sorting::Ascending.new(0, :invalid) end
13
+
14
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new { 0 }
15
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(nil) { 0 }
16
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(:nils_first) { 0 }
17
+ assert_instance_of Sorting::Ascending, Sorting::Ascending.new(:nils_last) { 0 }
18
+ assert_raises ArgumentError do Sorting::Ascending.new(:invalid) { 0 } end
19
+ end
20
+
21
+ test "#treat_nils" do
22
+ assert_equal nil, Sorting::Ascending.new(0).treat_nils
23
+ assert_equal nil, Sorting::Ascending.new(0, nil).treat_nils
24
+ assert_equal :nils_first, Sorting::Ascending.new(0, :nils_first).treat_nils
25
+ assert_equal :nils_last, Sorting::Ascending.new(0, :nils_last).treat_nils
26
+ end
27
+
28
+ test "#nils_first?" do
29
+ assert_equal false, Sorting::Ascending.new(0).nils_first?
30
+ assert_equal false, Sorting::Ascending.new(0, nil).nils_first?
31
+ assert_equal true, Sorting::Ascending.new(0, :nils_first).nils_first?
32
+ assert_equal false, Sorting::Ascending.new(0, :nils_last).nils_first?
33
+ end
34
+
35
+ test "#nils_last?" do
36
+ assert_equal false, Sorting::Ascending.new(0).nils_last?
37
+ assert_equal false, Sorting::Ascending.new(0, nil).nils_last?
38
+ assert_equal false, Sorting::Ascending.new(0, :nils_first).nils_last?
39
+ assert_equal true, Sorting::Ascending.new(0, :nils_last).nils_last?
40
+ end
41
+
42
+ test "#value" do
43
+ value = Object.new
44
+ assert_equal value, Sorting::Ascending.new(value).value
45
+ end
46
+
47
+ test "#<=>" do
48
+ assert_equal -1, Sorting::Ascending.new(0) <=> Sorting::Ascending.new(1)
49
+ assert_equal 0, Sorting::Ascending.new(1) <=> Sorting::Ascending.new(1)
50
+ assert_equal 1, Sorting::Ascending.new(1) <=> Sorting::Ascending.new(0)
51
+ assert_equal nil, Sorting::Ascending.new(0) <=> Sorting::Ascending.new(nil)
52
+ assert_equal -1, Sorting::Ascending.new(0, :nils_last) <=> Sorting::Ascending.new(nil)
53
+ assert_equal 1, Sorting::Ascending.new(0, :nils_first) <=> Sorting::Ascending.new(nil)
54
+
55
+ assert_equal -1, Sorting::Ascending.new { 0 } <=> Sorting::Ascending.new { 1 }
56
+ assert_equal 0, Sorting::Ascending.new { 1 } <=> Sorting::Ascending.new { 1 }
57
+ assert_equal 1, Sorting::Ascending.new { 1 } <=> Sorting::Ascending.new { 0 }
58
+ assert_equal nil, Sorting::Ascending.new { 0 } <=> Sorting::Ascending.new { nil }
59
+ assert_equal -1, Sorting::Ascending.new(:nils_last) { 0 } <=> Sorting::Ascending.new { nil }
60
+ assert_equal 1, Sorting::Ascending.new(:nils_first) { 0 } <=> Sorting::Ascending.new { nil }
61
+ end
62
+ end
63
+
64
+
65
+
66
+ suite "Descending" do
67
+ test "#initialize" do
68
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(0)
69
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(0, nil)
70
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(0, :nils_first)
71
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(0, :nils_last)
72
+ assert_raises ArgumentError do Sorting::Descending.new(0, :invalid) end
73
+
74
+ assert_instance_of Sorting::Descending, Sorting::Descending.new { 0 }
75
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(nil) { 0 }
76
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(:nils_first) { 0 }
77
+ assert_instance_of Sorting::Descending, Sorting::Descending.new(:nils_last) { 0 }
78
+ assert_raises ArgumentError do Sorting::Descending.new(:invalid) { 0 } end
79
+ end
80
+
81
+ test "#treat_nils" do
82
+ assert_equal nil, Sorting::Descending.new(0).treat_nils
83
+ assert_equal nil, Sorting::Descending.new(0, nil).treat_nils
84
+ assert_equal :nils_first, Sorting::Descending.new(0, :nils_first).treat_nils
85
+ assert_equal :nils_last, Sorting::Descending.new(0, :nils_last).treat_nils
86
+ end
87
+
88
+ test "#nils_first?" do
89
+ assert_equal false, Sorting::Descending.new(0).nils_first?
90
+ assert_equal false, Sorting::Descending.new(0, nil).nils_first?
91
+ assert_equal true, Sorting::Descending.new(0, :nils_first).nils_first?
92
+ assert_equal false, Sorting::Descending.new(0, :nils_last).nils_first?
93
+ end
94
+
95
+ test "#nils_last?" do
96
+ assert_equal false, Sorting::Descending.new(0).nils_last?
97
+ assert_equal false, Sorting::Descending.new(0, nil).nils_last?
98
+ assert_equal false, Sorting::Descending.new(0, :nils_first).nils_last?
99
+ assert_equal true, Sorting::Descending.new(0, :nils_last).nils_last?
100
+ end
101
+
102
+ test "#<=>" do
103
+ assert_equal 1, Sorting::Descending.new(0) <=> Sorting::Descending.new(1)
104
+ assert_equal 0, Sorting::Descending.new(1) <=> Sorting::Descending.new(1)
105
+ assert_equal -1, Sorting::Descending.new(1) <=> Sorting::Descending.new(0)
106
+ assert_equal nil, Sorting::Descending.new(0) <=> Sorting::Descending.new(nil)
107
+ assert_equal -1, Sorting::Descending.new(0, :nils_last) <=> Sorting::Descending.new(nil)
108
+ assert_equal 1, Sorting::Descending.new(0, :nils_first) <=> Sorting::Descending.new(nil)
109
+
110
+ assert_equal 1, Sorting::Descending.new { 0 } <=> Sorting::Descending.new { 1 }
111
+ assert_equal 0, Sorting::Descending.new { 1 } <=> Sorting::Descending.new { 1 }
112
+ assert_equal -1, Sorting::Descending.new { 1 } <=> Sorting::Descending.new { 0 }
113
+ assert_equal nil, Sorting::Descending.new { 0 } <=> Sorting::Descending.new { nil }
114
+ assert_equal -1, Sorting::Descending.new(:nils_last) { 0 } <=> Sorting::Descending.new { nil }
115
+ assert_equal 1, Sorting::Descending.new(:nils_first) { 0 } <=> Sorting::Descending.new { nil }
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+
3
+ require 'sorting/convenience'
4
+
5
+ suite "File sorting/convenience" do
6
+ test "Kernel#asc" do
7
+ assert_instance_of Sorting::Ascending, asc(0), "Kernel#asc is present"
8
+ assert_raises NoMethodError, "Kernel#asc is private" do Object.new.asc(0) end
9
+ end
10
+
11
+ test "Kernel::asc" do
12
+ assert_instance_of Sorting::Ascending, Kernel.asc(0), "Kernel::asc is present"
13
+ end
14
+
15
+ test "Sorting#asc" do
16
+ obj = Object.new.tap { |o| o.extend Sorting }
17
+ assert_instance_of Sorting::Ascending, obj.send(:asc, 0), "Sorting#asc is present" # bad test, since Kernel#asc exists too :-/
18
+ assert_raises NoMethodError, "Sorting#asc is private" do obj.asc(0) end
19
+ end
20
+
21
+ test "Sorting::asc" do
22
+ assert_instance_of Sorting::Ascending, Sorting.asc(0), "Sorting::asc is present"
23
+ end
24
+
25
+ test "Sorting::Helpers#asc" do
26
+ obj = Object.new.tap { |o| o.extend Sorting::Helpers }
27
+ assert_instance_of Sorting::Ascending, obj.send(:asc, 0), "Sorting#asc is present" # bad test, since Kernel#asc exists too :-/
28
+ assert_raises NoMethodError, "Sorting::Helpers#asc is private" do obj.asc(0) end
29
+ end
30
+
31
+
32
+
33
+ test "Kernel#desc" do
34
+ assert_instance_of Sorting::Descending, desc(0), "Kernel#desc is present"
35
+ assert_raises NoMethodError, "Kernel#desc is private" do Object.new.desc(0) end
36
+ end
37
+
38
+ test "Kernel::desc" do
39
+ assert_instance_of Sorting::Descending, Kernel.desc(0), "Kernel::desc is present"
40
+ end
41
+
42
+ test "Sorting#desc" do
43
+ obj = Object.new.tap { |o| o.extend Sorting }
44
+ assert_instance_of Sorting::Descending, obj.send(:desc, 0), "Sorting#desc is present" # bad test, since Kernel#desc exists too :-/
45
+ assert_raises NoMethodError, "Sorting#desc is private" do obj.desc(0) end
46
+ end
47
+
48
+ test "Sorting::desc" do
49
+ assert_instance_of Sorting::Descending, Sorting.desc(0), "Sorting::desc is present"
50
+ end
51
+
52
+ test "Sorting::Helpers#desc" do
53
+ obj = Object.new.tap { |o| o.extend Sorting::Helpers }
54
+ assert_instance_of Sorting::Descending, obj.send(:desc, 0), "Sorting#desc is present" # bad test, since Kernel#desc exists too :-/
55
+ assert_raises NoMethodError, "Sorting::Helpers#desc is private" do obj.desc(0) end
56
+ end
57
+ end
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+
3
+ require 'sorting/convenience'
4
+ require 'date'
5
+
6
+ suite "Sorting" do
7
+ suite "Smaller" do
8
+ test "#<=>" do
9
+ assert_equal -1, Sorting::Smaller <=> 1
10
+ assert_equal -1, Sorting::Smaller <=> Time.now
11
+ assert_equal -1, Sorting::Smaller <=> Date.today
12
+ assert_equal -1, Sorting::Smaller <=> Float::INFINITY
13
+ assert_equal -1, Sorting::Smaller <=> "Some String"
14
+ assert_equal -1, Sorting::Smaller <=> ["an", "array"]
15
+ assert_equal -1, Sorting::Smaller <=> Object.new
16
+
17
+ assert_equal 1, 1 <=> Sorting::Smaller
18
+ assert_equal 1, Time.now <=> Sorting::Smaller
19
+ assert_equal 1, Date.today <=> Sorting::Smaller
20
+ assert_equal 1, Float::INFINITY <=> Sorting::Smaller
21
+ assert_equal 1, "Some String" <=> Sorting::Smaller
22
+ assert_equal 1, ["an", "array"] <=> Sorting::Smaller
23
+ end
24
+ end
25
+
26
+ suite "Bigger" do
27
+ test "#<=>" do
28
+ assert_equal 1, Sorting::Bigger <=> 1
29
+ assert_equal 1, Sorting::Bigger <=> Time.now
30
+ assert_equal 1, Sorting::Bigger <=> Date.today
31
+ assert_equal 1, Sorting::Bigger <=> Float::INFINITY
32
+ assert_equal 1, Sorting::Bigger <=> "Some String"
33
+ assert_equal 1, Sorting::Bigger <=> ["an", "array"]
34
+ assert_equal 1, Sorting::Bigger <=> Object.new
35
+
36
+ assert_equal -1, 1 <=> Sorting::Bigger
37
+ assert_equal -1, Time.now <=> Sorting::Bigger
38
+ assert_equal -1, Date.today <=> Sorting::Bigger
39
+ assert_equal -1, Float::INFINITY <=> Sorting::Bigger
40
+ assert_equal -1, "Some String" <=> Sorting::Bigger
41
+ assert_equal -1, ["an", "array"] <=> Sorting::Bigger
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ require 'sorting/convenience'
4
+
5
+ suite "Sorting" do
6
+ test "#asc" do
7
+ assert_equal [1,2,3], [3,1,2].sort_by { |x| asc(x) }
8
+ end
9
+
10
+ test "#asc with :nils_last" do
11
+ assert_equal [1,2,3,nil], [3,nil,1,2].sort_by { |x| asc(x, :nils_last) }
12
+ end
13
+
14
+ test "#asc with :nils_first" do
15
+ assert_equal [nil,1,2,3], [3,nil,1,2].sort_by { |x| asc(x, :nils_first) }
16
+ end
17
+
18
+ test "#asc with lazy evaluation" do
19
+ assert_equal [1,2,3], [3,1,2].sort_by { |x| asc { x } }
20
+ end
21
+
22
+ test "#asc with lazy evaluation and :nils_last" do
23
+ assert_equal [1,2,3,nil], [3,nil,1,2].sort_by { |x| asc(:nils_last) { x } }
24
+ end
25
+
26
+ test "#asc with lazy evaluation and :nils_first" do
27
+ assert_equal [nil,1,2,3], [3,nil,1,2].sort_by { |x| asc(:nils_first) { x } }
28
+ end
29
+
30
+ test "#desc" do
31
+ assert_equal [3,2,1], [3,1,2].sort_by { |x| desc(x) }
32
+ end
33
+
34
+ test "#desc with :nils_last" do
35
+ assert_equal [3,2,1,nil], [3,nil,1,2].sort_by { |x| desc(x, :nils_last) }
36
+ end
37
+
38
+ test "#desc with :nils_first" do
39
+ assert_equal [nil,3,2,1], [3,nil,1,2].sort_by { |x| desc(x, :nils_first) }
40
+ end
41
+
42
+ test "#desc with lazy evaluation" do
43
+ assert_equal [3,2,1], [3,1,2].sort_by { |x| desc { x } }
44
+ end
45
+
46
+ test "#desc with lazy evaluation and :nils_last" do
47
+ assert_equal [3,2,1,nil], [3,nil,1,2].sort_by { |x| desc(:nils_last) { x } }
48
+ end
49
+
50
+ test "#desc with lazy evaluation and :nils_first" do
51
+ assert_equal [nil,3,2,1], [3,nil,1,2].sort_by { |x| desc(:nils_first) { x } }
52
+ end
53
+
54
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sorting
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Stefan Rusterholz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Helpful functionality for sorting and comparing.
15
+ email: stefan.rusterholz@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/sorting/ascending.rb
21
+ - lib/sorting/bigger.rb
22
+ - lib/sorting/convenience.rb
23
+ - lib/sorting/descending.rb
24
+ - lib/sorting/helpers.rb
25
+ - lib/sorting/smaller.rb
26
+ - lib/sorting/version.rb
27
+ - lib/sorting.rb
28
+ - test/lib/sorting_test/assertions.rb
29
+ - test/lib/sorting_test/helper.rb
30
+ - test/runner.rb
31
+ - test/unit/sorting/test_ascending_descending.rb
32
+ - test/unit/sorting/test_convenience.rb
33
+ - test/unit/sorting/test_smaller_bigger.rb
34
+ - test/unit/sorting/test_sorting.rb
35
+ - sorting.gemspec
36
+ - .yardopts
37
+ - LICENSE.txt
38
+ - Rakefile
39
+ - README.markdown
40
+ homepage: https://github.com/apeiros/sorting
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: 1.9.2
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>'
56
+ - !ruby/object:Gem::Version
57
+ version: 1.3.1
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 1.8.25
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Helpful functionality for sorting and comparing.
64
+ test_files: []
65
+ has_rdoc: