sem_ver 0.1.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 (4) hide show
  1. data/README.md +27 -0
  2. data/lib/sem_ver.rb +69 -0
  3. data/spec/sem_ver_spec.rb +136 -0
  4. metadata +69 -0
@@ -0,0 +1,27 @@
1
+ # SemVer [![Build Status](https://secure.travis-ci.org/porras/sem_ver.png?branch=master)](http://travis-ci.org/porras/sem_ver)
2
+
3
+ SemVer is a very simple [semantic version](http://semver.org/spec/v1.0.0.html) parser in Ruby. It takes a string and returns an object that can be validated and compared.
4
+
5
+ ## Examples
6
+
7
+ require 'sem_ver'
8
+
9
+ SemVer.parse('0.0.10').valid? # true
10
+ SemVer.parse('v1.0.10').valid? # true
11
+ SemVer.parse('X.10').valid? # false
12
+
13
+ SemVer.parse('1.0.0') > SemVer.parse('0.9.9') # true
14
+ SemVer.parse('1.0.1') >= SemVer.parse('1.0.0') # true
15
+ SemVer.parse('1.0.1') >= SemVer.parse('1.1.0') # false
16
+ SemVer.parse('1.0.0') == SemVer.parse('1.0.0-pre1') # false
17
+ SemVer.parse('1.0.0') > SemVer.parse('1.0.0-pre1') # true
18
+
19
+ ...
20
+
21
+ ## Alternatives
22
+
23
+ If you need more advanced things, [versionomy](http://dazuma.github.com/versionomy/) looks great.
24
+
25
+ ## Credits
26
+
27
+ Copyright © 2012 Sergio Gil, released under the MIT license
@@ -0,0 +1,69 @@
1
+ class SemVer
2
+ class InvalidVersion < Exception; end
3
+
4
+ include Comparable
5
+
6
+ def self.parse(*args)
7
+ new(*args)
8
+ end
9
+
10
+ def initialize(spec)
11
+ @spec = spec
12
+ end
13
+
14
+ def major
15
+ match && match[1].to_i
16
+ end
17
+
18
+ def minor
19
+ match && match[2].to_i
20
+ end
21
+
22
+ def patch
23
+ match && match[3].to_i
24
+ end
25
+
26
+ def prerelease
27
+ match && match[5]
28
+ end
29
+
30
+ def valid?
31
+ !!match
32
+ end
33
+
34
+ def <=>(other)
35
+ raise InvalidVersion.new(to_s) unless valid? && other.valid?
36
+ parts <=> other.parts
37
+ end
38
+
39
+ def to_s
40
+ return @spec unless valid?
41
+ "#{major}.#{minor}.#{patch}".tap do |v|
42
+ v << "-#{prerelease}" if prerelease
43
+ end
44
+ end
45
+
46
+ def inspect
47
+ "<#{'Invalid' unless valid?}Version: #{to_s}>"
48
+ end
49
+
50
+ protected
51
+
52
+ def parts
53
+ [major, minor, patch, prerelease_value]
54
+ end
55
+
56
+ private
57
+
58
+ def prerelease_value
59
+ prerelease ? prerelease.bytes.to_a : [Float::INFINITY]
60
+ end
61
+
62
+ def match
63
+ @match ||= @spec.match(/^v?(\d+)\.(\d+)\.(\d+)(\-(\w+))?$/)
64
+ end
65
+ end
66
+
67
+ unless defined?(Float::INFINITY)
68
+ Float::INFINITY = +1.0/0.0
69
+ end
@@ -0,0 +1,136 @@
1
+ require 'rspec'
2
+ require 'sem_ver'
3
+
4
+ describe SemVer do
5
+ describe '.parse' do
6
+ describe 'normal' do
7
+ let(:version) { SemVer.parse('3.1.2') }
8
+
9
+ example { version.major.should == 3 }
10
+ example { version.minor.should == 1 }
11
+ example { version.patch.should == 2 }
12
+ example { version.prerelease.should == nil }
13
+
14
+ describe 'order' do
15
+ example { SemVer.parse('0.0.10').should > SemVer.parse('0.0.9') }
16
+ example { SemVer.parse('0.1.0').should > SemVer.parse('0.0.2') }
17
+ example { SemVer.parse('1.0.0').should > SemVer.parse('0.9.9') }
18
+
19
+ example { SemVer.parse('0.0.1').should < SemVer.parse('0.0.2') }
20
+ example { SemVer.parse('0.0.2').should < SemVer.parse('0.1.0') }
21
+ example { SemVer.parse('0.9.9').should < SemVer.parse('1.0.0') }
22
+
23
+ example { SemVer.parse('0.0.1').should == SemVer.parse('0.0.1') }
24
+ example { SemVer.parse('0.0.2').should == SemVer.parse('0.0.2') }
25
+ example { SemVer.parse('0.9.9').should == SemVer.parse('0.9.9') }
26
+ end
27
+ end
28
+
29
+ describe 'prereleases' do
30
+ let(:version) { SemVer.parse('1.0.11-rc2') }
31
+
32
+ example { version.major.should == 1 }
33
+ example { version.minor.should == 0 }
34
+ example { version.patch.should == 11 }
35
+ example { version.prerelease.should == 'rc2' }
36
+
37
+ describe 'order' do
38
+ example { SemVer.parse('1.0.0').should > SemVer.parse('1.0.0-rc15') }
39
+ example { SemVer.parse('1.0.0-rc15').should < SemVer.parse('1.0.0') }
40
+ example { SemVer.parse('1.0.0-rc15').should == SemVer.parse('1.0.0-rc15') }
41
+ example { SemVer.parse('1.0.0-rc16').should > SemVer.parse('1.0.0-rc15') }
42
+ example { SemVer.parse('1.0.1-rc14').should > SemVer.parse('1.0.0-rc15') }
43
+ example { SemVer.parse('1.0.1-rc15').should > SemVer.parse('1.0.0-rc15') }
44
+ example { SemVer.parse('v1.0.0-rc15').should == SemVer.parse('1.0.0-rc15') }
45
+ end
46
+ end
47
+
48
+ describe 'vX.Y.Z' do
49
+ let(:version) { SemVer.parse('v3.1.2') }
50
+
51
+ example { version.major.should == 3 }
52
+ example { version.minor.should == 1 }
53
+ example { version.patch.should == 2 }
54
+ example { version.prerelease.should == nil }
55
+
56
+ describe 'equivalence' do
57
+ example { SemVer.parse('v0.0.1').should == SemVer.parse('0.0.1') }
58
+ example { SemVer.parse('v0.0.2').should == SemVer.parse('0.0.2') }
59
+ example { SemVer.parse('v0.9.9').should == SemVer.parse('0.9.9') }
60
+ end
61
+ end
62
+ end
63
+
64
+ describe '#valid?' do
65
+ example { SemVer.parse('1.0.0').should be_valid }
66
+ example { SemVer.parse('v1.0.0').should be_valid }
67
+ example { SemVer.parse('1.0.0-rc1').should be_valid }
68
+ example { SemVer.parse('v1.0.0-rc1').should be_valid }
69
+
70
+ example { SemVer.parse('v1.0.0-').should_not be_valid }
71
+ example { SemVer.parse('1.0.0-').should_not be_valid }
72
+
73
+ example { SemVer.parse('1.0-rc1').should_not be_valid }
74
+ example { SemVer.parse('v1.0-rc1').should_not be_valid }
75
+
76
+ example { SemVer.parse('1-rc1').should_not be_valid }
77
+ example { SemVer.parse('v1-rc1').should_not be_valid }
78
+
79
+ example { SemVer.parse('1.0').should_not be_valid }
80
+ example { SemVer.parse('v1.0').should_not be_valid }
81
+
82
+ example { SemVer.parse('1').should_not be_valid }
83
+ example { SemVer.parse('v1').should_not be_valid }
84
+
85
+ example { SemVer.parse('X.0.0').should_not be_valid }
86
+ example { SemVer.parse('vX.0.0').should_not be_valid }
87
+ example { SemVer.parse('X.0.0-rc1').should_not be_valid }
88
+ example { SemVer.parse('vX.0.0-rc1').should_not be_valid }
89
+ example { SemVer.parse('1.X.0').should_not be_valid }
90
+ example { SemVer.parse('v1.X.0').should_not be_valid }
91
+ example { SemVer.parse('1.X.0-rc1').should_not be_valid }
92
+ example { SemVer.parse('v1.X.0-rc1').should_not be_valid }
93
+ example { SemVer.parse('1.0.X').should_not be_valid }
94
+ example { SemVer.parse('v1.0.X').should_not be_valid }
95
+ example { SemVer.parse('1.0.X-rc1').should_not be_valid }
96
+ example { SemVer.parse('v1.0.X-rc1').should_not be_valid }
97
+
98
+ describe 'using a invalid version' do
99
+ let(:invalid_version) { SemVer.parse('1.0.wadus-rc1') }
100
+
101
+ example { invalid_version.major.should == nil }
102
+ example { invalid_version.minor.should == nil }
103
+ example { invalid_version.patch.should == nil }
104
+ example { invalid_version.prerelease.should == nil }
105
+
106
+ describe 'comparing' do
107
+ let(:valid_version) { SemVer.parse('1.0.0') }
108
+
109
+ example { expect { invalid_version < valid_version }.to raise_error(SemVer::InvalidVersion) }
110
+ example { expect { valid_version < invalid_version }.to raise_error(SemVer::InvalidVersion) }
111
+ example { expect { invalid_version <= valid_version }.to raise_error(SemVer::InvalidVersion) }
112
+ example { expect { valid_version <= invalid_version }.to raise_error(SemVer::InvalidVersion) }
113
+ example { expect { invalid_version > valid_version }.to raise_error(SemVer::InvalidVersion) }
114
+ example { expect { valid_version > invalid_version }.to raise_error(SemVer::InvalidVersion) }
115
+ example { expect { invalid_version >= valid_version }.to raise_error(SemVer::InvalidVersion) }
116
+ example { expect { valid_version >= invalid_version }.to raise_error(SemVer::InvalidVersion) }
117
+ example { expect { invalid_version == valid_version }.to raise_error(SemVer::InvalidVersion) }
118
+ example { expect { valid_version == invalid_version }.to raise_error(SemVer::InvalidVersion) }
119
+ example { expect { invalid_version != valid_version }.to raise_error(SemVer::InvalidVersion) }
120
+ example { expect { valid_version != invalid_version }.to raise_error(SemVer::InvalidVersion) }
121
+ end
122
+ end
123
+ end
124
+
125
+ describe '#to_s' do
126
+ example { SemVer.parse('1.0.0').to_s.should == '1.0.0' }
127
+ example { SemVer.parse('1.0.0-rc15').to_s.should == '1.0.0-rc15' }
128
+ example { SemVer.parse('1.0.wadus').to_s.should == '1.0.wadus' }
129
+ end
130
+
131
+ describe '#inspect' do
132
+ example { SemVer.parse('1.0.0').inspect.should == '<Version: 1.0.0>' }
133
+ example { SemVer.parse('1.0.0-rc15').inspect.should == '<Version: 1.0.0-rc15>' }
134
+ example { SemVer.parse('1.0.wadus').inspect.should == '<InvalidVersion: 1.0.wadus>' }
135
+ end
136
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sem_ver
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Sergio Gil
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-01-14 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: Semantic Version parser
22
+ email:
23
+ - sgilperez@gmail.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files: []
29
+
30
+ files:
31
+ - lib/sem_ver.rb
32
+ - README.md
33
+ - spec/sem_ver_spec.rb
34
+ homepage: http://github.com/porras/sem_ver
35
+ licenses: []
36
+
37
+ post_install_message:
38
+ rdoc_options: []
39
+
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.24
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Semantic Version parser
67
+ test_files:
68
+ - spec/sem_ver_spec.rb
69
+ has_rdoc: