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.
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