version_compare 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +145 -0
- data/Rakefile +32 -0
- data/lib/version_compare.rb +5 -0
- data/lib/version_compare/conversions.rb +36 -0
- data/lib/version_compare/version.rb +56 -0
- data/test/conversions_test.rb +101 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +29 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +29 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +56 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +0 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/test_helper.rb +18 -0
- data/test/version_compare_test.rb +181 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0ffcd0d56b6b7f030f3021bae075a475cf8c5073
|
4
|
+
data.tar.gz: 8be8c9d13a5ebc97be66ee2b3841259ea3655761
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7daa0dd6f3c4ea8917ef54cfcd46152f6e85ecd97157c7c471c5f03e1a1e7386f0c7d5563b3ca880370ee19ab49c969eb03ac2623624846635baab6a3739722a
|
7
|
+
data.tar.gz: 31bc14355f927875899dc7ac3070622e75344e81408fe609c91bf8aa7564d194a796b7fd4a38e7bfa152485e4f62cb8c2696fcd9416ab8458d2f22fe886a1514
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Paul Dobbins
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# Version Compare
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/version_compare)
|
4
|
+
|
5
|
+
Version Compare allows you to easily compare if one Version is >, >=, ==, !=, <,
|
6
|
+
or <= to another Version. It aims to be as light and flexible as possible. Inputs
|
7
|
+
can be a String, Integer, Float, Array, or any object that defines `#to_version`
|
8
|
+
to return one of the aforementioned types.
|
9
|
+
|
10
|
+
In an effort to remain simple, Version Compare only works with up to four
|
11
|
+
numeric values separated by periods:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
"<major>.<minor>.<tiny>.<patch>"
|
15
|
+
```
|
16
|
+
|
17
|
+
## Compatibility
|
18
|
+
|
19
|
+
Tested with:
|
20
|
+
|
21
|
+
* Ruby: MRI 1.9.3
|
22
|
+
* Ruby: MRI 2.0.0 +
|
23
|
+
|
24
|
+
## Installation
|
25
|
+
|
26
|
+
Add this line to your application's Gemfile:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
gem "version_compare"
|
30
|
+
```
|
31
|
+
|
32
|
+
And then execute:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
bundle
|
36
|
+
```
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
To get started, you can either use `Version.new(<value>)` or `Version(<value>)`.
|
41
|
+
To get the latter to work, you'll need to call `include ::Conversions` in the
|
42
|
+
class or context you're wanting to use it at.
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
class MyClass
|
46
|
+
include Conversions
|
47
|
+
|
48
|
+
def my_method
|
49
|
+
Version(1) > Version(2)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
Or, to test on the Rails Console:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
[1] pry(main)> include ::Conversions
|
58
|
+
=> Object
|
59
|
+
[2] pry(main)> Version(1.0) > Version(1)
|
60
|
+
=> false
|
61
|
+
|
62
|
+
# - OR (without using `include`) -
|
63
|
+
|
64
|
+
[1] pry(main)> Conversions.Version(1.0) > Conversions.Version(1)
|
65
|
+
=> false
|
66
|
+
```
|
67
|
+
|
68
|
+
Version Compare uses the `Comparable` mixin for comparisons, so you get all the
|
69
|
+
usual operators:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
Version(2) > Version(1) # => true
|
73
|
+
Version(1.2) > Version(1.2) # => false
|
74
|
+
Version("1.2.3") >= Version("1.2") # => true
|
75
|
+
Version("1.2.3.4") <= Version("1.2.3.4") # => true
|
76
|
+
Version([1, 2]) == Version(["1", "2"]) # => true
|
77
|
+
Version("1.2.0.0") == Version(1.2) # => true
|
78
|
+
Version("1.0.0.0") != Version(1) # => false
|
79
|
+
```
|
80
|
+
|
81
|
+
### Wait, so what exactly is this `Version` ... constant?
|
82
|
+
|
83
|
+
`Version()` is actually a conversion function. It follows the Ruby convention of
|
84
|
+
defining a conversion function that uses the same name as the class it
|
85
|
+
represents, such as how `Array()` converts inputs to an `Array` object.
|
86
|
+
Just like the standard Ruby conversion functions, `Version()` tries its hardest
|
87
|
+
to convert any Version-like input into a new `Version` object. Given a numeric,
|
88
|
+
string, or array input (which are all obvious conversions to make), `Version()`
|
89
|
+
is essentially the same as `Version.new()`. However, `Version()` is otherwise a
|
90
|
+
little more strict in that if you pass in an object that doesn't reasonably look
|
91
|
+
like a Version it will raise a `TypeError` exception. Doing the same for
|
92
|
+
`Version.new()` will ultimately just `#to_s` the input; and since almost
|
93
|
+
every object responds to `#to_s`, the result is that you may end up with a 0
|
94
|
+
version. For example:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
Version.new(OpenStruct.new(a: 1)).to_s # => "0"
|
98
|
+
```
|
99
|
+
|
100
|
+
### Can I pass my own custom objects into `Version()`?
|
101
|
+
|
102
|
+
Yes! All you have to do is define a `#to_version` implicit conversion method in
|
103
|
+
your object. Just have it return either a String, an Integer, a Float, or an
|
104
|
+
Array.
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
class MyObject
|
108
|
+
VERSION = 1.9
|
109
|
+
def to_version
|
110
|
+
Version.new(VERSION.to_s)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
Version(MyObject.new) > Version(2.0) # => false
|
115
|
+
```
|
116
|
+
|
117
|
+
### Why do you seem to excited about the custom object thing?
|
118
|
+
|
119
|
+
Because, it opens up the world! Here's an example:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
# Given a Rails app:
|
123
|
+
|
124
|
+
# /config/application.rb
|
125
|
+
module Dummy
|
126
|
+
class Application < Rails::Application
|
127
|
+
# ...
|
128
|
+
|
129
|
+
VERSION = "1.2".freeze
|
130
|
+
|
131
|
+
def to_version
|
132
|
+
Version.new(VERSION) # Or Version.new([1, 2]) or whatever...
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Now, from the context of that Rails app you can call:
|
138
|
+
Version(Rails.application) > Version(1.0) # => true
|
139
|
+
```
|
140
|
+
|
141
|
+
So you see, the sky is the limit...
|
142
|
+
|
143
|
+
## Author
|
144
|
+
|
145
|
+
- Paul Dobbins
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'VersionCompare'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
Bundler::GemHelper.install_tasks
|
21
|
+
|
22
|
+
require 'rake/testtask'
|
23
|
+
|
24
|
+
Rake::TestTask.new(:test) do |t|
|
25
|
+
t.libs << 'lib'
|
26
|
+
t.libs << 'test'
|
27
|
+
t.pattern = 'test/**/*_test.rb'
|
28
|
+
t.verbose = false
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task default: :test
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Conversions is meant to be a common module used to define standard conversion
|
2
|
+
# methods. Anytime one of the standard conversion methods are needed, the
|
3
|
+
# Conversions module can be included and then used freely.
|
4
|
+
#
|
5
|
+
module Conversions
|
6
|
+
require_relative "version"
|
7
|
+
|
8
|
+
# The `Version()` conversion method is defined as a module_function so that it
|
9
|
+
# may also be called directly without needing to include the Conversions module
|
10
|
+
# if so desired.
|
11
|
+
# @example
|
12
|
+
# Conversions.Version(1.2).to_s # => "1.2"
|
13
|
+
module_function
|
14
|
+
|
15
|
+
# Strict conversion method for creating a `Version` object out of anything
|
16
|
+
# that sensibly is a Version.
|
17
|
+
# @param [Object] value the object to be converted
|
18
|
+
# @example
|
19
|
+
# Version(1) # => #<Version:0x007fd8144ea658 @major=1, @minor=nil, @tiny=nil, @patch=nil>
|
20
|
+
# Version(1.2) # => #<Version:0x007fd8144ea658 @major=1, @minor=2, @tiny=nil, @patch=nil>
|
21
|
+
# Version("1.2.3") # => #<Version:0x007fd8144ea658 @major=1, @minor=2, @tiny=3, @patch=nil>
|
22
|
+
# Version(["1", "2", "3", "4"]) # => #<Version:0x007fd8144f98b0 @major=1, @minor=2, @tiny=3, @patch=4>
|
23
|
+
def Version(value)
|
24
|
+
case value
|
25
|
+
when String,
|
26
|
+
Integer,
|
27
|
+
Float,
|
28
|
+
-> val { val.respond_to?(:to_ary) }
|
29
|
+
Version.new(value)
|
30
|
+
when -> val { val.respond_to?(:to_version) }
|
31
|
+
value.to_version
|
32
|
+
else
|
33
|
+
raise TypeError, "Cannot convert #{value.inspect} to Version"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Version
|
2
|
+
include Comparable
|
3
|
+
|
4
|
+
# Version component names
|
5
|
+
NAMES = [:major, :minor, :tiny, :patch].freeze
|
6
|
+
|
7
|
+
attr_accessor *NAMES
|
8
|
+
|
9
|
+
def initialize(value)
|
10
|
+
@major, @minor, @tiny, @patch = begin
|
11
|
+
if value.respond_to?(:to_ary)
|
12
|
+
value.to_ary.map(&:to_i)
|
13
|
+
elsif value.respond_to?(:to_version)
|
14
|
+
value.to_version.to_a
|
15
|
+
else
|
16
|
+
value.to_s.split('.').map(&:to_i)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Implicit conversion method
|
22
|
+
def to_version
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
[major, minor, tiny, patch].compact.join('.')
|
28
|
+
end
|
29
|
+
alias :to_str :to_s
|
30
|
+
|
31
|
+
def to_f
|
32
|
+
to_s.to_f
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_a
|
36
|
+
NAMES.map { |name| send(name) }.compact
|
37
|
+
end
|
38
|
+
alias :to_ary :to_a
|
39
|
+
|
40
|
+
# Version components comparison method. Uses Comparable to assess whether
|
41
|
+
# This Version's component value or the other Version's component value is
|
42
|
+
# greater or lesser. The first value to be found as greater or lesser
|
43
|
+
# determines which Version object is greater or lesser.
|
44
|
+
#
|
45
|
+
# Missing Version components are treated as 0 values, which effectively gives
|
46
|
+
# them no weight in the comparison.
|
47
|
+
#
|
48
|
+
# @params [Version] other the other Version object we are comparing with
|
49
|
+
def <=>(other)
|
50
|
+
NAMES.each do |name|
|
51
|
+
result = send(name).to_i <=> other.send(name).to_i
|
52
|
+
return result unless result.zero?
|
53
|
+
end
|
54
|
+
0
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Conversions do
|
4
|
+
describe "conversion function" do
|
5
|
+
it "works on integers" do
|
6
|
+
assert { Version(1).class == Version }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "works on floats" do
|
10
|
+
assert { Version(1.2).class == Version }
|
11
|
+
end
|
12
|
+
|
13
|
+
it "works on strings" do
|
14
|
+
assert { Version("1.2.3.4").class == Version }
|
15
|
+
end
|
16
|
+
|
17
|
+
it "works on arrays" do
|
18
|
+
assert { Version([1, 2, 3, 4]).instance_of?(Version) }
|
19
|
+
assert { Version([1, 2, 3, 4]) == Version("1.2.3.4") }
|
20
|
+
assert { Version(["1", "2", "3", "4"]) == Version("1.2.3.4") }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "works on Versions" do
|
24
|
+
assert { Version(Version(1.2)).instance_of?(Version) }
|
25
|
+
assert { Version(Version(1.2)) == Version(1.2) }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "explicit conversions" do
|
30
|
+
describe "#to_s" do
|
31
|
+
it "returns string regardless of input" do
|
32
|
+
assert { Version(1).to_s == "1" }
|
33
|
+
assert { Version(1.2).to_s == "1.2" }
|
34
|
+
assert { Version("1.2.3").to_s == "1.2.3" }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#to_f" do
|
39
|
+
it "returns float when major only" do
|
40
|
+
assert { Version(1).to_f == 1.0 }
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns float when major and minor" do
|
44
|
+
assert { Version(1.0).to_f == 1.0 }
|
45
|
+
assert { Version(1.2).to_f == 1.2 }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns truncated float when more than just major and minor" do
|
49
|
+
assert { Version("1.0.0").to_f == 1.0 }
|
50
|
+
assert { Version("1.1.9").to_f == 1.1 }
|
51
|
+
assert { Version("1.0.0.0").to_f == 1.0 }
|
52
|
+
assert { Version("1.1.9.9").to_f == 1.1 }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#to_a" do
|
57
|
+
it "returns an array of integers" do
|
58
|
+
assert { Version(1).to_a == [1] }
|
59
|
+
assert { Version(1.0).to_a == [1, 0] }
|
60
|
+
assert { Version("1.2.3").to_a == [1, 2, 3] }
|
61
|
+
assert { Version("1.2.3.4").to_a == [1, 2, 3, 4] }
|
62
|
+
assert { Version(["1", "2", "3", "4"]).to_a == [1, 2, 3, 4] }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "implicit conversions" do
|
68
|
+
describe "string concatination" do
|
69
|
+
it "concatinates" do
|
70
|
+
assert { ("version: " + Version("1.2.3.4")) == "version: 1.2.3.4" }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe "CustomObjects" do
|
75
|
+
describe "without #to_version" do
|
76
|
+
it "raises TypeError when attempting to convert custom objects that don't implement #to_version" do
|
77
|
+
assert { rescuing { Version(Object.new) }.instance_of?(TypeError) }
|
78
|
+
deny { rescuing { Version.new(Object.new) }.is_a?(StandardError) }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "with #to_version" do
|
83
|
+
before do
|
84
|
+
class CustomObject < Object
|
85
|
+
VERSION = 1.9
|
86
|
+
def to_version
|
87
|
+
Version.new(VERSION.to_s)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@obj = CustomObject.new
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns a Version object" do
|
95
|
+
assert { Version(@obj).instance_of?(Version) }
|
96
|
+
assert { Version.new(@obj).instance_of?(Version) }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
== README
|
2
|
+
|
3
|
+
This README would normally document whatever steps are necessary to get the
|
4
|
+
application up and running.
|
5
|
+
|
6
|
+
Things you may want to cover:
|
7
|
+
|
8
|
+
* Ruby version
|
9
|
+
|
10
|
+
* System dependencies
|
11
|
+
|
12
|
+
* Configuration
|
13
|
+
|
14
|
+
* Database creation
|
15
|
+
|
16
|
+
* Database initialization
|
17
|
+
|
18
|
+
* How to run the test suite
|
19
|
+
|
20
|
+
* Services (job queues, cache servers, search engines, etc.)
|
21
|
+
|
22
|
+
* Deployment instructions
|
23
|
+
|
24
|
+
* ...
|
25
|
+
|
26
|
+
|
27
|
+
Please feel free to use a different markup language if you do not plan to run
|
28
|
+
<tt>rake doc:app</tt>.
|
data/test/dummy/Rakefile
ADDED