naturalsorter 2.0.5 → 2.0.6
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.
- data/README.markdown +25 -31
- data/lib/natcmp.rb +2 -2
- data/lib/naturalsorter.rb +45 -59
- data/lib/naturalsorter/version.rb +1 -1
- data/lib/version_tag_recognizer.rb +33 -56
- data/lib/versioncmp.rb +40 -45
- data/spec/naturalsorter_spec.rb +53 -49
- metadata +2 -2
data/README.markdown
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# NaturalSorter
|
|
2
2
|
|
|
3
|
-
[](http://badge.fury.io/rb/naturalsorter)
|
|
4
4
|
[](http://www.versioneye.com/package/naturalsorter)
|
|
5
|
+
[](https://travis-ci.org/versioneye/naturalsorter)
|
|
6
|
+
[](https://codeclimate.com/github/versioneye/naturalsorter)
|
|
5
7
|
|
|
6
8
|
|
|
7
9
|
## The Mission
|
|
@@ -14,47 +16,39 @@ If you are sorting this in ruby with ".sort" you will get this result
|
|
|
14
16
|
|
|
15
17
|
`["init20", "init200", "init30"]`
|
|
16
18
|
|
|
17
|
-
Because the default sort method does not recognize the numbers in the string. The NaturalSorter will return this result.
|
|
19
|
+
Because the default sort method does not recognize the numbers in the string. The NaturalSorter will return this result.
|
|
18
20
|
|
|
19
21
|
`["init20", "init30", "init200"]`
|
|
20
22
|
|
|
21
23
|
## Version Sorting
|
|
22
|
-
This fork contains some special algorithms to sort version numbers in a natural order. This project is used at <https://www.versioneye.com> to show versions of selected open source projects.
|
|
24
|
+
This fork contains some special algorithms to sort version numbers in a natural order. This project is used at <https://www.versioneye.com> to show versions of selected open source projects.
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
## API
|
|
26
28
|
|
|
27
|
-
This 2 methods are sorting a simple array of Strings. The name of the methods and the parameters are self explained.
|
|
28
|
-
|
|
29
|
-
`Naturalsorter::Sorter.sort(array, caseinsesitive)`
|
|
30
|
-
|
|
31
|
-
`Naturalsorter::Sorter.sort_desc(array, caseinsesitive)`
|
|
32
|
-
|
|
33
|
-
And this here is for more advanced sorting. Where you can put in a array of objects and the method which should called on every object for comparison.
|
|
34
|
-
|
|
35
|
-
`Naturalsorter::Sorter.sort_by_method(array, method, caseinsesitive)`
|
|
29
|
+
This 2 methods are sorting a simple array of Strings. The name of the methods and the parameters are self explained.
|
|
36
30
|
|
|
37
|
-
`Naturalsorter::Sorter.
|
|
31
|
+
`Naturalsorter::Sorter.sort(array, caseinsesitive = false, asc = true)`
|
|
38
32
|
|
|
39
|
-
|
|
33
|
+
And this here is for more advanced sorting. Where you can put in a array of objects and the method which should called on every object for comparison.
|
|
40
34
|
|
|
41
|
-
`Naturalsorter::Sorter.
|
|
35
|
+
`Naturalsorter::Sorter.sort_by_method(array, method, caseinsesitive = false, asc = true)`
|
|
42
36
|
|
|
43
|
-
|
|
37
|
+
This methods are based on a different algo. Spezially optimizied for sorting version strings.
|
|
44
38
|
|
|
45
|
-
|
|
39
|
+
`Naturalsorter::Sorter.sort_version(array, asc = true)`
|
|
46
40
|
|
|
47
|
-
|
|
41
|
+
This here is again for an array with objects. Spezially optimizied for sorting version strings.
|
|
48
42
|
|
|
49
|
-
`Naturalsorter::Sorter.
|
|
43
|
+
`Naturalsorter::Sorter.sort_version_by_method(array, method, asc = true )`
|
|
50
44
|
|
|
51
45
|
Get the newest version from the both given.
|
|
52
46
|
|
|
53
|
-
`Naturalsorter::Sorter.get_newest_version(first, second)`
|
|
47
|
+
`Naturalsorter::Sorter.get_newest_version(first, second)`
|
|
54
48
|
|
|
55
49
|
Is a bigger than b?
|
|
56
50
|
|
|
57
|
-
`Naturalsorter::Sorter.bigger?(a, b)`
|
|
51
|
+
`Naturalsorter::Sorter.bigger?(a, b)`
|
|
58
52
|
|
|
59
53
|
Is a bigger than b or equal?
|
|
60
54
|
|
|
@@ -68,19 +62,19 @@ Is a smaller than b or equal?
|
|
|
68
62
|
|
|
69
63
|
`Naturalsorter::Sorter.smaller_or_equal?(a, b)`
|
|
70
64
|
|
|
71
|
-
This is for the Ruby GEM notaiton '~>'. For example '~>1.1' fits '1.2' and '1.9' and '1.14'. But not 2.0.
|
|
72
|
-
The parameter version would be for example '~>1.1' and the parameter newest_version would be the
|
|
73
|
-
current newest version of the GEM, for example "2.0". The method will return false in this case
|
|
74
|
-
because '~>1.1' doesn't fit anymore the newest version.
|
|
65
|
+
This is for the Ruby GEM notaiton '~>'. For example '~>1.1' fits '1.2' and '1.9' and '1.14'. But not 2.0.
|
|
66
|
+
The parameter version would be for example '~>1.1' and the parameter newest_version would be the
|
|
67
|
+
current newest version of the GEM, for example "2.0". The method will return false in this case
|
|
68
|
+
because '~>1.1' doesn't fit anymore the newest version.
|
|
75
69
|
|
|
76
|
-
`Naturalsorter::Sorter.is_version_current?(version, newest_version)`
|
|
70
|
+
`Naturalsorter::Sorter.is_version_current?(version, newest_version)`
|
|
77
71
|
|
|
78
72
|
|
|
79
|
-
## Installation
|
|
73
|
+
## Installation
|
|
80
74
|
|
|
81
75
|
You should add this line to your Gemfile
|
|
82
76
|
|
|
83
|
-
`gem 'naturalsorter', '2.0.
|
|
77
|
+
`gem 'naturalsorter', '2.0.6'`
|
|
84
78
|
|
|
85
79
|
and run this command in your app root directory
|
|
86
80
|
|
|
@@ -88,13 +82,13 @@ and run this command in your app root directory
|
|
|
88
82
|
|
|
89
83
|
## How To Use - Examples
|
|
90
84
|
|
|
91
|
-
After the installation you can use it like this:
|
|
85
|
+
After the installation you can use it like this:
|
|
92
86
|
|
|
93
87
|
`Naturalsorter::Sorter.sort(["a400", "a5", "a1"], true)`
|
|
94
88
|
|
|
95
89
|
it will return the array ["a1", "a5", "a400"]. The second paramter is for "caseinsesitive".
|
|
96
90
|
|
|
97
|
-
If you have more advanced objects you want to sort, you should use the second method. Assume you have a Class User with 3 attributes: "firstname", "lastname", "age" and you want to sort an array of class Users by "firstname".
|
|
91
|
+
If you have more advanced objects you want to sort, you should use the second method. Assume you have a Class User with 3 attributes: "firstname", "lastname", "age" and you want to sort an array of class Users by "firstname".
|
|
98
92
|
|
|
99
93
|
`Naturalsorter::Sorter.sort_by_method(users, "firstname", true)`
|
|
100
94
|
|
|
@@ -109,5 +103,5 @@ will return the array ["1.1", "1.2", "1.10"]
|
|
|
109
103
|
|
|
110
104
|
## Alan Davies
|
|
111
105
|
|
|
112
|
-
The first 4 methods in this librarie are internal based on the natcmp implementation from Alan Davies. All glorry to him for his awesome work.
|
|
106
|
+
The first 4 methods in this librarie are internal based on the natcmp implementation from Alan Davies. All glorry to him for his awesome work.
|
|
113
107
|
|
data/lib/natcmp.rb
CHANGED
|
@@ -61,10 +61,10 @@ def self.natcmp(str1, str2, caseInsensitive=false)
|
|
|
61
61
|
|
|
62
62
|
case (num1 <=> num2)
|
|
63
63
|
when -1 then return -1
|
|
64
|
-
when
|
|
64
|
+
when 1 then return 1
|
|
65
65
|
end
|
|
66
66
|
when -1 then return -1
|
|
67
|
-
when
|
|
67
|
+
when 1 then return 1
|
|
68
68
|
end # case
|
|
69
69
|
|
|
70
70
|
end # while
|
data/lib/naturalsorter.rb
CHANGED
|
@@ -29,95 +29,81 @@ module Naturalsorter
|
|
|
29
29
|
|
|
30
30
|
class Sorter
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
def self.sort(array, caseinsesitive)
|
|
32
|
+
def self.sort(array, caseinsesitive = false , asc = true )
|
|
34
33
|
return array if (array.nil? || array.empty?)
|
|
35
|
-
|
|
34
|
+
if asc
|
|
35
|
+
return array.sort { |a, b| Natcmp.natcmp(a, b, caseinsesitive) }
|
|
36
|
+
else
|
|
37
|
+
return array.sort { |a, b| Natcmp.natcmp(b, a, caseinsesitive) }
|
|
38
|
+
end
|
|
36
39
|
end
|
|
37
40
|
|
|
38
|
-
def self.sort_desc(array, caseinsesitive)
|
|
39
|
-
return array if (array.nil? || array.empty?)
|
|
40
|
-
array.sort { |a, b| Natcmp.natcmp(b, a, caseinsesitive) }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
|
|
44
41
|
# 'Natural order' sort for an array of objects.
|
|
45
|
-
def self.sort_by_method(array, method, caseinsesitive)
|
|
46
|
-
return array if (array.nil? || array.empty?)
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
def self.sort_by_method(array, method, caseinsesitive = false, asc = true)
|
|
43
|
+
return array if (array.nil? || array.empty? || array.length == 1)
|
|
44
|
+
if asc
|
|
45
|
+
array.sort { |a,b| Natcmp.natcmp( a.send(method), b.send(method), caseinsesitive) }
|
|
46
|
+
else
|
|
47
|
+
array.sort { |a, b| Natcmp.natcmp(b.send(method), a.send(method), caseinsesitive) }
|
|
48
|
+
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def self.sort_by_method_desc(array, method, caseinsesitive)
|
|
52
|
-
return array if (array.nil? || array.empty?)
|
|
53
|
-
return array if array.length == 1
|
|
54
|
-
array.sort { |a, b| Natcmp.natcmp(b.send(method), a.send(method), caseinsesitive) }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def self.sort_version(array)
|
|
59
|
-
return array if (array.nil? || array.empty?)
|
|
60
|
-
array.sort { |a,b| Versioncmp.compare( a, b ) }
|
|
61
|
-
end
|
|
62
51
|
|
|
63
|
-
def self.
|
|
64
|
-
return array if (array.nil? || array.empty?)
|
|
65
|
-
|
|
52
|
+
def self.sort_version(array, asc = true)
|
|
53
|
+
return array if (array.nil? || array.empty? || array.length == 1)
|
|
54
|
+
if asc
|
|
55
|
+
array.sort { |a,b| Versioncmp.compare( a, b ) }
|
|
56
|
+
else
|
|
57
|
+
array.sort { |a,b| Versioncmp.compare( b, a ) }
|
|
58
|
+
end
|
|
66
59
|
end
|
|
67
60
|
|
|
68
61
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
62
|
+
def self.sort_version_by_method(array, method, asc = true )
|
|
63
|
+
return array if (array.nil? || array.empty? || array.length == 1 )
|
|
64
|
+
if asc
|
|
65
|
+
array.sort { |a,b| Versioncmp.compare(a.send(method), b.send(method)) }
|
|
66
|
+
else
|
|
67
|
+
array.sort { |a,b| Versioncmp.compare(b.send(method), a.send(method)) }
|
|
68
|
+
end
|
|
74
69
|
end
|
|
75
|
-
|
|
76
|
-
def self.sort_version_by_method_desc(array, method)
|
|
77
|
-
return array if (array.nil? || array.empty?)
|
|
78
|
-
return array if array.length == 1
|
|
79
|
-
array.sort { |a,b| Versioncmp.compare(b.send(method), a.send(method)) }
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
|
|
70
|
+
|
|
83
71
|
|
|
84
72
|
def self.get_newest_version(first, second)
|
|
85
73
|
array = [first, second]
|
|
86
74
|
array = array.sort { |a,b| Versioncmp.compare( a, b ) }
|
|
87
75
|
array.last
|
|
88
76
|
end
|
|
77
|
+
|
|
78
|
+
def self.get_newest(a, b)
|
|
79
|
+
Versioncmp.replace_leading_vs a, b
|
|
80
|
+
Sorter.get_newest_version(a, b)
|
|
81
|
+
end
|
|
89
82
|
|
|
90
83
|
def self.bigger?(a, b)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
return false if a.eql?( b )
|
|
85
|
+
newest = self.get_newest a, b
|
|
86
|
+
newest.eql?( a )
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.smaller?(a, b)
|
|
90
|
+
return false if b.eql?( a )
|
|
91
|
+
newest = self.get_newest a, b
|
|
92
|
+
newest.eql?( b )
|
|
96
93
|
end
|
|
97
94
|
|
|
98
95
|
def self.bigger_or_equal?(a, b)
|
|
99
|
-
Versioncmp.replace_leading_v( a )
|
|
100
|
-
Versioncmp.replace_leading_v( b )
|
|
101
96
|
return true if a.eql?(b)
|
|
102
|
-
newest =
|
|
97
|
+
newest = self.get_newest a, b
|
|
103
98
|
newest.eql?(a)
|
|
104
99
|
end
|
|
105
100
|
|
|
106
|
-
def self.smaller?(a, b)
|
|
107
|
-
Versioncmp.replace_leading_v( a )
|
|
108
|
-
Versioncmp.replace_leading_v( b )
|
|
109
|
-
return false if a.eql?(b)
|
|
110
|
-
newest = Sorter.get_newest_version(a, b)
|
|
111
|
-
newest.eql?(b)
|
|
112
|
-
end
|
|
113
|
-
|
|
114
101
|
def self.smaller_or_equal?(a, b)
|
|
115
|
-
Versioncmp.replace_leading_v( a )
|
|
116
|
-
Versioncmp.replace_leading_v( b )
|
|
117
102
|
return true if a.eql?(b)
|
|
118
|
-
newest =
|
|
103
|
+
newest = self.get_newest a, b
|
|
119
104
|
newest.eql?(b)
|
|
120
105
|
end
|
|
106
|
+
|
|
121
107
|
|
|
122
108
|
|
|
123
109
|
# This is for the GEM notaiton ~>
|
|
@@ -28,10 +28,14 @@ class VersionTagRecognizer
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def self.tagged? value
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
self.
|
|
31
|
+
return true if self.alpha?(value)
|
|
32
|
+
return true if self.beta?(value)
|
|
33
|
+
return true if self.dev?(value)
|
|
34
|
+
return true if self.rc?(value)
|
|
35
|
+
return true if self.snapshot?(value)
|
|
36
|
+
return true if self.pre?(value)
|
|
37
|
+
return true if self.jbossorg?(value)
|
|
38
|
+
return false
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
def self.remove_tag value
|
|
@@ -54,53 +58,25 @@ class VersionTagRecognizer
|
|
|
54
58
|
end
|
|
55
59
|
|
|
56
60
|
def self.remove_minimum_stability val
|
|
57
|
-
if val.match(/@.*$/)
|
|
58
|
-
val.gsub!(/@.*$/, "")
|
|
59
|
-
end
|
|
61
|
+
val.gsub!(/@.*$/, "") if val.match(/@.*$/)
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def self.does_it_fit_stability?( version_number, stability )
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if self.stable?( version_number ) ||
|
|
79
|
-
self.rc?( version_number ) ||
|
|
80
|
-
self.beta?( version_number )
|
|
81
|
-
return true
|
|
82
|
-
end
|
|
83
|
-
elsif stability.casecmp( A_STABILITY_ALPHA ) == 0
|
|
84
|
-
if self.stable?( version_number ) ||
|
|
85
|
-
self.rc?( version_number ) ||
|
|
86
|
-
self.beta?( version_number ) ||
|
|
87
|
-
self.alpha?( version_number )
|
|
88
|
-
return true
|
|
89
|
-
end
|
|
90
|
-
elsif stability.casecmp( A_STABILITY_SNAPSHOT ) == 0
|
|
91
|
-
if self.stable?( version_number ) ||
|
|
92
|
-
self.rc?( version_number ) ||
|
|
93
|
-
self.pre?( version_number ) ||
|
|
94
|
-
self.beta?( version_number ) ||
|
|
95
|
-
self.alpha?( version_number ) ||
|
|
96
|
-
self.snapshot?( version_number )
|
|
97
|
-
return true
|
|
98
|
-
end
|
|
99
|
-
elsif stability.casecmp( A_STABILITY_DEV ) == 0
|
|
100
|
-
return true
|
|
101
|
-
else
|
|
102
|
-
return false
|
|
103
|
-
end
|
|
65
|
+
stable = self.stable?( version_number )
|
|
66
|
+
pre = stable || self.pre?( version_number )
|
|
67
|
+
rc = stable || self.rc?( version_number )
|
|
68
|
+
beta = rc || self.beta?( version_number )
|
|
69
|
+
alpha = beta || self.alpha?( version_number )
|
|
70
|
+
snapshot = alpha || self.pre?( version_number ) || self.snapshot?( version_number )
|
|
71
|
+
|
|
72
|
+
return true if (stability.casecmp( A_STABILITY_STABLE ) == 0) && stable
|
|
73
|
+
return true if (stability.casecmp( A_STABILITY_PRE ) == 0) && pre
|
|
74
|
+
return true if (stability.casecmp( A_STABILITY_RC ) == 0) && rc
|
|
75
|
+
return true if (stability.casecmp( A_STABILITY_BETA ) == 0) && beta
|
|
76
|
+
return true if (stability.casecmp( A_STABILITY_ALPHA ) == 0) && alpha
|
|
77
|
+
return true if (stability.casecmp( A_STABILITY_SNAPSHOT ) == 0) && snapshot
|
|
78
|
+
return true if (stability.casecmp( A_STABILITY_DEV ) == 0)
|
|
79
|
+
return false
|
|
104
80
|
end
|
|
105
81
|
|
|
106
82
|
def self.stability_tag_for( version )
|
|
@@ -131,14 +107,15 @@ class VersionTagRecognizer
|
|
|
131
107
|
end
|
|
132
108
|
|
|
133
109
|
def self.stable? value
|
|
134
|
-
if value.match(/.+RELEASE.*/i)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
!self.
|
|
141
|
-
!self.
|
|
110
|
+
return true if value.match(/.+RELEASE.*/i)
|
|
111
|
+
return true if value.match(/.+BUILD.*/i)
|
|
112
|
+
return true if value.match(/.+FINAL.*/i)
|
|
113
|
+
return true if value.match(/.+SP.*/i)
|
|
114
|
+
return true if value.match(/.+GA.*/i)
|
|
115
|
+
|
|
116
|
+
!self.alpha?(value) and !self.beta?(value) and
|
|
117
|
+
!self.dev?(value) and !self.pre?(value) and
|
|
118
|
+
!self.rc?(value) and !value.match(/.+SEC.*/i) and
|
|
142
119
|
!self.snapshot?(value) and !value.match(/.+M.+/i)
|
|
143
120
|
end
|
|
144
121
|
|
data/lib/versioncmp.rb
CHANGED
|
@@ -29,17 +29,12 @@ class Versioncmp
|
|
|
29
29
|
#
|
|
30
30
|
def self.compare(a_val, b_val)
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
32
|
+
a_empty = a_val.nil? || a_val.empty?
|
|
33
|
+
b_empty = b_val.nil? || b_val.empty?
|
|
35
34
|
|
|
36
|
-
if
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if a_val.nil? && b_val.nil?
|
|
41
|
-
return -1
|
|
42
|
-
end
|
|
35
|
+
return 0 if a_empty && b_empty
|
|
36
|
+
return 1 if (a_empty == false) && b_empty
|
|
37
|
+
return -1 if (b_empty == false) && a_empty
|
|
43
38
|
|
|
44
39
|
a = pre_process a_val
|
|
45
40
|
b = pre_process b_val
|
|
@@ -48,14 +43,14 @@ class Versioncmp
|
|
|
48
43
|
offset2 = 0;
|
|
49
44
|
|
|
50
45
|
for i in 0..100
|
|
51
|
-
break if offset1 >= a.length() || offset2 >= b.length()
|
|
46
|
+
break if offset1 >= a.length() || offset2 >= b.length()
|
|
52
47
|
|
|
53
48
|
part1 = Versioncmp.get_a_piece_of_the_cake(offset1, a);
|
|
54
49
|
part2 = Versioncmp.get_a_piece_of_the_cake(offset2, b);
|
|
55
|
-
|
|
50
|
+
|
|
56
51
|
return -1 if Versioncmp.timestamp?(part1) && part2.length() < 8
|
|
57
52
|
return 1 if Versioncmp.timestamp?(part2) && part1.length() < 8
|
|
58
|
-
|
|
53
|
+
|
|
59
54
|
offset1 += part1.length() + 1;
|
|
60
55
|
offset2 += part2.length() + 1;
|
|
61
56
|
|
|
@@ -64,10 +59,10 @@ class Versioncmp
|
|
|
64
59
|
bi = part2.to_i;
|
|
65
60
|
result = Versioncmp.compare_int(ai, bi);
|
|
66
61
|
return result if result != 0
|
|
67
|
-
next
|
|
62
|
+
next
|
|
68
63
|
elsif ( !part1.match(/^[0-9]+$/) && !part2.match(/^[0-9]+$/) )
|
|
69
64
|
result = double_scope_checker(a, b)
|
|
70
|
-
return result if result != 0
|
|
65
|
+
return result if result != 0
|
|
71
66
|
result = Versioncmp.compare_string(part1, part2)
|
|
72
67
|
return result if (result != 0)
|
|
73
68
|
next
|
|
@@ -78,12 +73,12 @@ class Versioncmp
|
|
|
78
73
|
return -1;
|
|
79
74
|
end
|
|
80
75
|
end
|
|
81
|
-
result = Versioncmp.check_for_tags(a, b)
|
|
76
|
+
result = Versioncmp.check_for_tags(a, b)
|
|
82
77
|
return result
|
|
83
78
|
end
|
|
84
|
-
|
|
79
|
+
|
|
85
80
|
# Tags are RC, alpha, beta, dev and so on.
|
|
86
|
-
#
|
|
81
|
+
#
|
|
87
82
|
def self.check_for_tags(a, b)
|
|
88
83
|
big = String.new(a)
|
|
89
84
|
small = String.new(b)
|
|
@@ -97,24 +92,24 @@ class Versioncmp
|
|
|
97
92
|
return Versioncmp.compare_string_length(a, b)
|
|
98
93
|
end
|
|
99
94
|
end
|
|
100
|
-
self.compare_string_length_odd(a, b)
|
|
95
|
+
self.compare_string_length_odd(a, b)
|
|
101
96
|
end
|
|
102
97
|
|
|
103
98
|
def self.double_scope_checker(a, b)
|
|
104
99
|
if VersionTagRecognizer.tagged?(a) && VersionTagRecognizer.tagged?(b)
|
|
105
|
-
a_without_scope
|
|
100
|
+
a_without_scope = VersionTagRecognizer.remove_tag a
|
|
106
101
|
b_without_scope = VersionTagRecognizer.remove_tag b
|
|
107
102
|
if a_without_scope.eql? b_without_scope
|
|
108
103
|
return VersionTagRecognizer.compare_tags(a, b)
|
|
109
104
|
end
|
|
110
105
|
end
|
|
111
|
-
0
|
|
106
|
+
0
|
|
112
107
|
end
|
|
113
|
-
|
|
108
|
+
|
|
114
109
|
def self.get_a_piece_of_the_cake(offset, cake)
|
|
115
110
|
for z in 0..100
|
|
116
111
|
offsetz = offset + z
|
|
117
|
-
break if offsetz > cake.length()
|
|
112
|
+
break if offsetz > cake.length()
|
|
118
113
|
p = cake[ offset..offset + z ]
|
|
119
114
|
if ( p.match(/^\w+\.$/) != nil )
|
|
120
115
|
break
|
|
@@ -126,21 +121,21 @@ class Versioncmp
|
|
|
126
121
|
piece = cake[offset..offset + z ]
|
|
127
122
|
return piece
|
|
128
123
|
end
|
|
129
|
-
|
|
124
|
+
|
|
130
125
|
def self.timestamp?(part)
|
|
131
126
|
return part.length() == 8 && part.match(/^[0-9]+$/) != nil
|
|
132
127
|
end
|
|
133
128
|
|
|
134
|
-
def self.pre_process val
|
|
129
|
+
def self.pre_process val
|
|
135
130
|
a = replace_x_dev val
|
|
136
|
-
replace_leading_v a
|
|
131
|
+
replace_leading_v a
|
|
137
132
|
replace_99_does_not_exist a
|
|
138
|
-
replace_timestamps a
|
|
139
|
-
VersionTagRecognizer.remove_minimum_stability a
|
|
140
|
-
a
|
|
133
|
+
replace_timestamps a
|
|
134
|
+
VersionTagRecognizer.remove_minimum_stability a
|
|
135
|
+
a
|
|
141
136
|
end
|
|
142
137
|
|
|
143
|
-
def self.replace_99_does_not_exist val
|
|
138
|
+
def self.replace_99_does_not_exist val
|
|
144
139
|
if val.eql?("99.0-does-not-exist")
|
|
145
140
|
val.gsub!("99.0-does-not-exist", "0.0.0")
|
|
146
141
|
end
|
|
@@ -148,17 +143,17 @@ class Versioncmp
|
|
|
148
143
|
|
|
149
144
|
# Some glory Java Devs used the timestamp as version string
|
|
150
145
|
# http://www.versioneye.com/package/commons-beanutils--commons-beanutils
|
|
151
|
-
# Ganz grosses Kino
|
|
146
|
+
# Ganz grosses Kino !
|
|
152
147
|
#
|
|
153
148
|
def self.replace_timestamps val
|
|
154
149
|
if val.match(/^[0-9]{8}$/)
|
|
155
150
|
val.gsub!(/^[0-9]{8}$/, "0.0.0")
|
|
156
|
-
elsif val.match(/^[0-9]{8}.[0-9]{6}$/)
|
|
151
|
+
elsif val.match(/^[0-9]{8}.[0-9]{6}$/)
|
|
157
152
|
val.gsub!(/^[0-9]{8}.[0-9]{6}$/, "0.0.0")
|
|
158
153
|
end
|
|
159
154
|
end
|
|
160
155
|
|
|
161
|
-
def self.replace_x_dev val
|
|
156
|
+
def self.replace_x_dev val
|
|
162
157
|
new_val = String.new(val)
|
|
163
158
|
if val.eql?("dev-master")
|
|
164
159
|
new_val = "9999999"
|
|
@@ -170,16 +165,17 @@ class Versioncmp
|
|
|
170
165
|
new_val
|
|
171
166
|
end
|
|
172
167
|
|
|
173
|
-
def self.replace_leading_v val
|
|
174
|
-
if val.match(/^v[0-9]+/)
|
|
175
|
-
val.gsub!(/^v/, "")
|
|
176
|
-
end
|
|
168
|
+
def self.replace_leading_v val
|
|
169
|
+
val.gsub!(/^v/, "") if val.match(/^v[0-9]+/)
|
|
177
170
|
end
|
|
178
171
|
|
|
179
|
-
|
|
172
|
+
def self.replace_leading_vs a, b
|
|
173
|
+
self.replace_leading_v a
|
|
174
|
+
self.replace_leading_v b
|
|
175
|
+
end
|
|
180
176
|
|
|
181
177
|
def self.check_jquery_versioning(part1, part2)
|
|
182
|
-
# --- START ---- special case for awesome jquery shitty verison numbers
|
|
178
|
+
# --- START ---- special case for awesome jquery shitty verison numbers
|
|
183
179
|
if ( part1.match(/^[0-9]+[a-zA-Z]+[0-9]+$/) != nil && part2.match(/^[0-9]+$/) != nil )
|
|
184
180
|
part1_1 = part1.match(/^[0-9]+/)
|
|
185
181
|
result = Versioncmp.compare_int(part1_1[0], part2)
|
|
@@ -199,7 +195,7 @@ class Versioncmp
|
|
|
199
195
|
end
|
|
200
196
|
|
|
201
197
|
return nil
|
|
202
|
-
# --- END ---- special case for awesome jquery shitty verison numbers
|
|
198
|
+
# --- END ---- special case for awesome jquery shitty verison numbers
|
|
203
199
|
end
|
|
204
200
|
|
|
205
201
|
def self.compare_int(ai, bi)
|
|
@@ -207,20 +203,19 @@ class Versioncmp
|
|
|
207
203
|
return 0 if (ai == bi)
|
|
208
204
|
return 1
|
|
209
205
|
end
|
|
210
|
-
|
|
206
|
+
|
|
211
207
|
def self.compare_string(a, b)
|
|
212
208
|
return 0 if a.eql? b
|
|
213
|
-
return
|
|
214
|
-
return 1
|
|
209
|
+
return Natcmp.natcmp(a, b)
|
|
215
210
|
end
|
|
216
211
|
|
|
217
|
-
def self.compare_string_length(a, b)
|
|
212
|
+
def self.compare_string_length(a, b)
|
|
218
213
|
return 0 if a.length() == b.length()
|
|
219
214
|
return 1 if a.length() < b.length()
|
|
220
215
|
return -1
|
|
221
216
|
end
|
|
222
217
|
|
|
223
|
-
def self.compare_string_length_odd(a, b)
|
|
218
|
+
def self.compare_string_length_odd(a, b)
|
|
224
219
|
return 1 if a.length > b.length
|
|
225
220
|
return -1 if a.length < b.length
|
|
226
221
|
return 0
|
data/spec/naturalsorter_spec.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require "naturalsorter"
|
|
2
2
|
|
|
3
3
|
describe Naturalsorter::Sorter do
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
describe "sort" do
|
|
6
6
|
it "cba is abc" do
|
|
7
7
|
Naturalsorter::Sorter.sort(["c", "b", "a"], true).should eql(["a", "b", "c"])
|
|
@@ -12,13 +12,13 @@ describe Naturalsorter::Sorter do
|
|
|
12
12
|
end
|
|
13
13
|
describe "sort_desc" do
|
|
14
14
|
it "cba is abc" do
|
|
15
|
-
Naturalsorter::Sorter.
|
|
15
|
+
Naturalsorter::Sorter.sort(["c", "b", "a"], true, false).should eql(["c", "b", "a"])
|
|
16
16
|
end
|
|
17
17
|
it "c400b5a1 is a1b5c400" do
|
|
18
|
-
Naturalsorter::Sorter.
|
|
18
|
+
Naturalsorter::Sorter.sort(["a5", "a400", "a1"], true, false).should eql(["a400", "a5", "a1"])
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
describe "sort_by_method" do
|
|
23
23
|
it "c400b5a1 is a1b5c400" do
|
|
24
24
|
Naturalsorter::Sorter.sort_by_method(["a400", "a5", "a1"], "to_s", true).should eql(["a1", "a5", "a400"])
|
|
@@ -26,11 +26,11 @@ describe Naturalsorter::Sorter do
|
|
|
26
26
|
end
|
|
27
27
|
describe "sort_by_method_desc" do
|
|
28
28
|
it "a5 a400 a1 is a400 a5 a1" do
|
|
29
|
-
Naturalsorter::Sorter.
|
|
29
|
+
Naturalsorter::Sorter.sort_by_method(["a5", "a400", "a1"], "to_s", true, false).should eql(["a400", "a5", "a1"])
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
|
|
34
34
|
describe "sort_version" do
|
|
35
35
|
|
|
36
36
|
it "1.1 is 1.1" do
|
|
@@ -40,23 +40,23 @@ describe Naturalsorter::Sorter do
|
|
|
40
40
|
it "1.1 is bigger than 20030211.134440" do
|
|
41
41
|
Naturalsorter::Sorter.sort_version(["1.1", "20030211.134440"]).should eql(["20030211.134440", "1.1"])
|
|
42
42
|
end
|
|
43
|
-
|
|
43
|
+
|
|
44
44
|
it "1.1, 1.0 is 1.0, 1.1" do
|
|
45
45
|
Naturalsorter::Sorter.sort_version(["1.1", "1.0"]).should eql(["1.0", "1.1"])
|
|
46
46
|
end
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
it "1.0, 1.1 is 1.0, 1.1" do
|
|
49
49
|
Naturalsorter::Sorter.sort_version(["1.0", "1.1"]).should eql(["1.0", "1.1"])
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
it "4.5, 1.0 is 1.0, 4.5" do
|
|
53
53
|
Naturalsorter::Sorter.sort_version(["4.5", "1.0"]).should eql(["1.0", "4.5"])
|
|
54
54
|
end
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
it "1.0, 4.5 is 1.0, 4.5" do
|
|
57
57
|
Naturalsorter::Sorter.sort_version(["1.0", "4.5"]).should eql(["1.0", "4.5"])
|
|
58
58
|
end
|
|
59
|
-
|
|
59
|
+
|
|
60
60
|
it "1.2, 1.1 is 1.1, 1.2" do
|
|
61
61
|
Naturalsorter::Sorter.sort_version(["0.4", "0.1", "1.1", "1.2", "1.0"]).should eql(["0.1", "0.4", "1.0", "1.1", "1.2"])
|
|
62
62
|
end
|
|
@@ -66,15 +66,15 @@ describe Naturalsorter::Sorter do
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it "1.2, 1.1 is 1.1, 1.2" do
|
|
69
|
-
Naturalsorter::Sorter.
|
|
69
|
+
Naturalsorter::Sorter.sort_version(["0.4", "0.1", "1.1", "1.2", "1.0", "1.0.RC1"], false).should eql(["1.2", "1.1", "1.0", "1.0.RC1", "0.4", "0.1"])
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
it "1.2, 1.1 is 1.1, 1.2" do
|
|
73
|
-
Naturalsorter::Sorter.
|
|
73
|
+
Naturalsorter::Sorter.sort_version(["0.4", "0.1", "1.1", "1.1.1", "1.2", "1.2.1", "1.0", "1.0.RC1"], false).should eql(["1.2.1", "1.2", "1.1.1", "1.1", "1.0", "1.0.RC1", "0.4", "0.1"])
|
|
74
74
|
end
|
|
75
|
-
|
|
75
|
+
|
|
76
76
|
it "sorts this to the end 20040121.140929" do
|
|
77
|
-
Naturalsorter::Sorter.
|
|
77
|
+
Naturalsorter::Sorter.sort_version(["0.4", "0.1", "20040121.140929", "1.1.1", "1.2", "1.2.1", "1.0", "1.0.RC1"], false).should eql(["1.2.1", "1.2", "1.1.1", "1.0", "1.0.RC1", "0.4", "0.1", "20040121.140929"])
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
it "1.2, 1.1 is 1.1, 1.2" do
|
|
@@ -89,37 +89,41 @@ describe Naturalsorter::Sorter do
|
|
|
89
89
|
Naturalsorter::Sorter.sort_version(["1.1.RC1", "1.1", "1.0"]).should eql(["1.0", "1.1.RC1", "1.1"])
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
+
it "sorts 2.1.0-beta11 higher than 2.1.0-beta9" do
|
|
93
|
+
Naturalsorter::Sorter.sort_version(["2.1.0-beta11", "2.1.0-beta9"]).should eql(["2.1.0-beta9", "2.1.0-beta11"])
|
|
94
|
+
end
|
|
95
|
+
|
|
92
96
|
end
|
|
93
|
-
|
|
94
|
-
describe "is_version_current?" do
|
|
95
|
-
it "returns true" do
|
|
97
|
+
|
|
98
|
+
describe "is_version_current?" do
|
|
99
|
+
it "returns true" do
|
|
96
100
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "1.1.9").should be_true
|
|
97
101
|
end
|
|
98
|
-
it "returns true" do
|
|
102
|
+
it "returns true" do
|
|
99
103
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "1.1.2").should be_true
|
|
100
104
|
end
|
|
101
|
-
it "returns true" do
|
|
105
|
+
it "returns true" do
|
|
102
106
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "1.1.12").should be_true
|
|
103
107
|
end
|
|
104
|
-
it "returns false" do
|
|
108
|
+
it "returns false" do
|
|
105
109
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "1.2.0").should be_false
|
|
106
110
|
end
|
|
107
|
-
it "returns false" do
|
|
111
|
+
it "returns false" do
|
|
108
112
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "1.2").should be_false
|
|
109
113
|
end
|
|
110
|
-
it "returns false" do
|
|
114
|
+
it "returns false" do
|
|
111
115
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "2.0").should be_false
|
|
112
116
|
end
|
|
113
|
-
it "returns false" do
|
|
117
|
+
it "returns false" do
|
|
114
118
|
Naturalsorter::Sorter.is_version_current?("1.1.1", "2").should be_false
|
|
115
119
|
end
|
|
116
|
-
it "returns false" do
|
|
120
|
+
it "returns false" do
|
|
117
121
|
Naturalsorter::Sorter.is_version_current?("1.1", "2.0").should be_false
|
|
118
122
|
end
|
|
119
123
|
end
|
|
120
|
-
|
|
121
|
-
describe "get_newest_version" do
|
|
122
|
-
|
|
124
|
+
|
|
125
|
+
describe "get_newest_version" do
|
|
126
|
+
|
|
123
127
|
it "returns 2.0" do
|
|
124
128
|
Naturalsorter::Sorter.get_newest_version("1.1", "2.0").should eql("2.0")
|
|
125
129
|
end
|
|
@@ -153,11 +157,11 @@ describe Naturalsorter::Sorter do
|
|
|
153
157
|
it "returns still 1.11.1" do
|
|
154
158
|
Naturalsorter::Sorter.get_newest_version("1.10.x-dev", "1.11.1").should eql("1.11.1")
|
|
155
159
|
end
|
|
156
|
-
|
|
160
|
+
|
|
157
161
|
end
|
|
158
|
-
|
|
159
|
-
describe "bigger?" do
|
|
160
|
-
|
|
162
|
+
|
|
163
|
+
describe "bigger?" do
|
|
164
|
+
|
|
161
165
|
it "returns true" do
|
|
162
166
|
Naturalsorter::Sorter.bigger?("1.1", "1.0").should be_true
|
|
163
167
|
end
|
|
@@ -179,11 +183,11 @@ describe Naturalsorter::Sorter do
|
|
|
179
183
|
it "returns false" do
|
|
180
184
|
Naturalsorter::Sorter.bigger?("2.20", "3.0").should be_false
|
|
181
185
|
end
|
|
182
|
-
|
|
186
|
+
|
|
183
187
|
end
|
|
184
|
-
|
|
185
|
-
describe "bigger_or_equal?" do
|
|
186
|
-
|
|
188
|
+
|
|
189
|
+
describe "bigger_or_equal?" do
|
|
190
|
+
|
|
187
191
|
it "returns true" do
|
|
188
192
|
Naturalsorter::Sorter.bigger_or_equal?("1.1", "1.0").should be_true
|
|
189
193
|
end
|
|
@@ -205,11 +209,11 @@ describe Naturalsorter::Sorter do
|
|
|
205
209
|
it "returns false" do
|
|
206
210
|
Naturalsorter::Sorter.bigger_or_equal?("2.20", "3.0").should be_false
|
|
207
211
|
end
|
|
208
|
-
|
|
212
|
+
|
|
209
213
|
end
|
|
210
|
-
|
|
211
|
-
describe "smaller?" do
|
|
212
|
-
|
|
214
|
+
|
|
215
|
+
describe "smaller?" do
|
|
216
|
+
|
|
213
217
|
it "returns false" do
|
|
214
218
|
Naturalsorter::Sorter.smaller?("1.1", "1.0").should be_false
|
|
215
219
|
end
|
|
@@ -225,11 +229,11 @@ describe Naturalsorter::Sorter do
|
|
|
225
229
|
it "returns true" do
|
|
226
230
|
Naturalsorter::Sorter.smaller?("2.20", "3.0").should be_true
|
|
227
231
|
end
|
|
228
|
-
|
|
232
|
+
|
|
229
233
|
end
|
|
230
|
-
|
|
231
|
-
describe "smaller_or_equal?" do
|
|
232
|
-
|
|
234
|
+
|
|
235
|
+
describe "smaller_or_equal?" do
|
|
236
|
+
|
|
233
237
|
it "returns false" do
|
|
234
238
|
Naturalsorter::Sorter.smaller_or_equal?("1.1", "1.0").should be_false
|
|
235
239
|
end
|
|
@@ -248,7 +252,7 @@ describe Naturalsorter::Sorter do
|
|
|
248
252
|
it "returns true" do
|
|
249
253
|
Naturalsorter::Sorter.smaller_or_equal?("2.20", "v3.0").should be_true
|
|
250
254
|
end
|
|
251
|
-
|
|
255
|
+
|
|
252
256
|
end
|
|
253
|
-
|
|
254
|
-
end
|
|
257
|
+
|
|
258
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: naturalsorter
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.6
|
|
5
5
|
prerelease:
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2013-
|
|
13
|
+
date: 2013-06-18 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rspec
|