version_compare 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +145 -0
  4. data/Rakefile +32 -0
  5. data/lib/version_compare.rb +5 -0
  6. data/lib/version_compare/conversions.rb +36 -0
  7. data/lib/version_compare/version.rb +56 -0
  8. data/test/conversions_test.rb +101 -0
  9. data/test/dummy/README.rdoc +28 -0
  10. data/test/dummy/Rakefile +6 -0
  11. data/test/dummy/app/assets/javascripts/application.js +13 -0
  12. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  13. data/test/dummy/app/controllers/application_controller.rb +5 -0
  14. data/test/dummy/app/helpers/application_helper.rb +2 -0
  15. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  16. data/test/dummy/bin/bundle +3 -0
  17. data/test/dummy/bin/rails +4 -0
  18. data/test/dummy/bin/rake +4 -0
  19. data/test/dummy/config.ru +4 -0
  20. data/test/dummy/config/application.rb +29 -0
  21. data/test/dummy/config/boot.rb +5 -0
  22. data/test/dummy/config/database.yml +25 -0
  23. data/test/dummy/config/environment.rb +5 -0
  24. data/test/dummy/config/environments/development.rb +29 -0
  25. data/test/dummy/config/environments/production.rb +80 -0
  26. data/test/dummy/config/environments/test.rb +36 -0
  27. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  28. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  29. data/test/dummy/config/initializers/inflections.rb +16 -0
  30. data/test/dummy/config/initializers/mime_types.rb +5 -0
  31. data/test/dummy/config/initializers/secret_token.rb +12 -0
  32. data/test/dummy/config/initializers/session_store.rb +3 -0
  33. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  34. data/test/dummy/config/locales/en.yml +23 -0
  35. data/test/dummy/config/routes.rb +56 -0
  36. data/test/dummy/log/development.log +0 -0
  37. data/test/dummy/log/test.log +0 -0
  38. data/test/dummy/public/404.html +58 -0
  39. data/test/dummy/public/422.html +58 -0
  40. data/test/dummy/public/500.html +57 -0
  41. data/test/dummy/public/favicon.ico +0 -0
  42. data/test/test_helper.rb +18 -0
  43. data/test/version_compare_test.rb +181 -0
  44. 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
+ [![Gem Version](https://badge.fury.io/rb/version_compare.png)](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,5 @@
1
+ require "version_compare/conversions"
2
+
3
+ module VersionCompare
4
+ autoload :Version, "version_compare/version"
5
+ end
@@ -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>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Dummy::Application.load_tasks