semantic_puppet 0.1.3 → 1.0.3

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.
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
- require "semantic_puppet"
3
+ require "semantic_puppet/gem_version"
4
4
 
5
5
  spec = Gem::Specification.new do |s|
6
6
  # Metadata
@@ -20,12 +20,16 @@ spec = Gem::Specification.new do |s|
20
20
  s.require_paths = ["lib"]
21
21
 
22
22
  # Dependencies
23
- s.required_ruby_version = '>= 1.8.7'
23
+ s.required_ruby_version = '>= 1.9.3'
24
24
 
25
+ s.add_development_dependency "json", "~> 1.8.3" if RUBY_VERSION < '2.0'
25
26
  s.add_development_dependency "rake"
26
27
  s.add_development_dependency "rspec"
27
- s.add_development_dependency "simplecov"
28
- s.add_development_dependency "cane"
29
- s.add_development_dependency "yard"
30
- s.add_development_dependency "redcarpet"
28
+
29
+ unless RUBY_PLATFORM =~ /java/
30
+ s.add_development_dependency "simplecov"
31
+ s.add_development_dependency "cane"
32
+ s.add_development_dependency "yard"
33
+ s.add_development_dependency "redcarpet"
34
+ end
31
35
  end
@@ -8,7 +8,6 @@ if ENV['COVERAGE']
8
8
  end
9
9
 
10
10
  RSpec.configure do |config|
11
- config.treat_symbols_as_metadata_keys_with_true_values = true
12
11
  config.run_all_when_everything_filtered = true
13
12
  config.filter_run :focus
14
13
 
@@ -5,7 +5,7 @@ describe SemanticPuppet::Dependency::UnsatisfiableGraph do
5
5
 
6
6
  let(:modules) { %w[ foo bar baz ] }
7
7
  let(:graph) { double('Graph', :modules => modules) }
8
- let(:instance) { described_class.new(graph) }
8
+ let(:instance) { described_class.new(graph, ['a']) }
9
9
 
10
10
  subject { instance }
11
11
 
@@ -40,27 +40,27 @@ describe SemanticPuppet::Dependency do
40
40
  end
41
41
 
42
42
  context 'with one source' do
43
- let(:source) { double('Source') }
43
+ let(:source) { double('Source', :priority => 0) }
44
44
 
45
45
  before { SemanticPuppet::Dependency.add_source(source) }
46
46
 
47
47
  it 'queries the source for release information' do
48
- source.should_receive(:fetch).with('module_name').and_return([])
48
+ expect(source).to receive(:fetch).with('module_name').and_return([])
49
49
 
50
50
  SemanticPuppet::Dependency.query('module_name' => '1.0.0')
51
51
  end
52
52
 
53
53
  it 'queries the source for each dependency' do
54
- source.should_receive(:fetch).with('module_name').and_return([
54
+ expect(source).to receive(:fetch).with('module_name').and_return([
55
55
  create_release(source, 'module_name', '1.0.0', 'bar' => '1.0.0')
56
56
  ])
57
- source.should_receive(:fetch).with('bar').and_return([])
57
+ expect(source).to receive(:fetch).with('bar').and_return([])
58
58
 
59
59
  SemanticPuppet::Dependency.query('module_name' => '1.0.0')
60
60
  end
61
61
 
62
62
  it 'queries the source for each dependency only once' do
63
- source.should_receive(:fetch).with('module_name').and_return([
63
+ expect(source).to receive(:fetch).with('module_name').and_return([
64
64
  create_release(
65
65
  source,
66
66
  'module_name',
@@ -68,23 +68,23 @@ describe SemanticPuppet::Dependency do
68
68
  'bar' => '1.0.0', 'baz' => '0.0.2'
69
69
  )
70
70
  ])
71
- source.should_receive(:fetch).with('bar').and_return([
71
+ expect(source).to receive(:fetch).with('bar').and_return([
72
72
  create_release(source, 'bar', '1.0.0', 'baz' => '0.0.3')
73
73
  ])
74
- source.should_receive(:fetch).with('baz').once.and_return([])
74
+ expect(source).to receive(:fetch).with('baz').once.and_return([])
75
75
 
76
76
  SemanticPuppet::Dependency.query('module_name' => '1.0.0')
77
77
  end
78
78
 
79
79
  it 'returns a ModuleRelease with the requested dependencies' do
80
- source.stub(:fetch).and_return([])
80
+ allow(source).to receive(:fetch).and_return([])
81
81
 
82
82
  result = SemanticPuppet::Dependency.query('foo' => '1.0.0', 'bar' => '1.0.0')
83
83
  expect(result.dependency_names).to match_array %w[ foo bar ]
84
84
  end
85
85
 
86
86
  it 'populates the returned ModuleRelease with related dependencies' do
87
- source.stub(:fetch).and_return(
87
+ allow(source).to receive(:fetch).and_return(
88
88
  [ foo = create_release(source, 'foo', '1.0.0', 'bar' => '1.0.0') ],
89
89
  [ bar = create_release(source, 'bar', '1.0.0') ]
90
90
  )
@@ -95,7 +95,7 @@ describe SemanticPuppet::Dependency do
95
95
  end
96
96
 
97
97
  it 'populates all returned ModuleReleases with related dependencies' do
98
- source.stub(:fetch).and_return(
98
+ allow(source).to receive(:fetch).and_return(
99
99
  [ foo = create_release(source, 'foo', '1.0.0', 'bar' => '1.0.0') ],
100
100
  [ bar = create_release(source, 'bar', '1.0.0', 'baz' => '0.1.0') ],
101
101
  [ baz = create_release(source, 'baz', '0.1.0', 'baz' => '1.0.0') ]
@@ -109,9 +109,9 @@ describe SemanticPuppet::Dependency do
109
109
  end
110
110
 
111
111
  context 'with multiple sources' do
112
- let(:source1) { double('SourceOne') }
113
- let(:source2) { double('SourceTwo') }
114
- let(:source3) { double('SourceThree') }
112
+ let(:source1) { double('SourceOne', :priority => 0) }
113
+ let(:source2) { double('SourceTwo', :priority => 0) }
114
+ let(:source3) { double('SourceThree', :priority => 0) }
115
115
 
116
116
  before do
117
117
  SemanticPuppet::Dependency.add_source(source1)
@@ -120,23 +120,23 @@ describe SemanticPuppet::Dependency do
120
120
  end
121
121
 
122
122
  it 'queries each source in turn' do
123
- source1.should_receive(:fetch).with('module_name').and_return([])
124
- source2.should_receive(:fetch).with('module_name').and_return([])
125
- source3.should_receive(:fetch).with('module_name').and_return([])
123
+ expect(source1).to receive(:fetch).with('module_name').and_return([])
124
+ expect(source2).to receive(:fetch).with('module_name').and_return([])
125
+ expect(source3).to receive(:fetch).with('module_name').and_return([])
126
126
 
127
127
  SemanticPuppet::Dependency.query('module_name' => '1.0.0')
128
128
  end
129
129
 
130
130
  it 'resolves all dependencies against all sources' do
131
- source1.should_receive(:fetch).with('module_name').and_return([
131
+ expect(source1).to receive(:fetch).with('module_name').and_return([
132
132
  create_release(source1, 'module_name', '1.0.0', 'bar' => '1.0.0')
133
133
  ])
134
- source2.should_receive(:fetch).with('module_name').and_return([])
135
- source3.should_receive(:fetch).with('module_name').and_return([])
134
+ expect(source2).to receive(:fetch).with('module_name').and_return([])
135
+ expect(source3).to receive(:fetch).with('module_name').and_return([])
136
136
 
137
- source1.should_receive(:fetch).with('bar').and_return([])
138
- source2.should_receive(:fetch).with('bar').and_return([])
139
- source3.should_receive(:fetch).with('bar').and_return([])
137
+ expect(source1).to receive(:fetch).with('bar').and_return([])
138
+ expect(source2).to receive(:fetch).with('bar').and_return([])
139
+ expect(source3).to receive(:fetch).with('bar').and_return([])
140
140
 
141
141
  SemanticPuppet::Dependency.query('module_name' => '1.0.0')
142
142
  end
@@ -147,7 +147,7 @@ describe SemanticPuppet::Dependency do
147
147
  def add_source_modules(name, versions, deps = {})
148
148
  versions = Array(versions)
149
149
  releases = versions.map { |ver| create_release(source, name, ver, deps) }
150
- source.stub(:fetch).with(name).and_return(modules[name].concat(releases))
150
+ allow(source).to receive(:fetch).with(name).and_return(modules[name].concat(releases))
151
151
  end
152
152
 
153
153
  def subject(specs)
@@ -187,7 +187,7 @@ describe SemanticPuppet::Dependency do
187
187
  it 'returns the greatest prerelease version matching the range' do
188
188
  add_source_modules('foo', %w[ 1.0.0 1.1.0-a 1.1.0-b 2.0.0 ])
189
189
 
190
- expect(foo('1.1.x')).to eql %w[ 1.1.0-b ]
190
+ expect(foo('>1.1.0-a <2.0.0')).to eql %w[ 1.1.0-b ]
191
191
  expect(foo('1.1.0-a')).to eql %w[ 1.1.0-a ]
192
192
  end
193
193
  end
@@ -226,7 +226,7 @@ describe SemanticPuppet::Dependency do
226
226
 
227
227
  context 'when the dependency has no stable versions' do
228
228
  it 'returns the greatest prerelease version matching the range' do
229
- add_source_modules('foo', '1.1.0', 'bar' => '1.1.x')
229
+ add_source_modules('foo', '1.1.0', 'bar' => '>=1.1.0-0 <1.2.0')
230
230
  add_source_modules('foo', '1.1.1', 'bar' => '1.1.0-a')
231
231
  add_source_modules('bar', %w[ 1.0.0 1.1.0-a 1.1.0-b 2.0.0 ])
232
232
 
@@ -4,43 +4,49 @@ require 'semantic_puppet/version'
4
4
  describe SemanticPuppet::VersionRange do
5
5
 
6
6
  describe '.parse' do
7
+ def self.test_expressions(expressions)
8
+ expressions.each do |range, vs|
9
+ test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
10
+ end
11
+ end
12
+
7
13
  def self.test_range(range_list, str, includes, excludes)
8
14
  Array(range_list).each do |expr|
9
15
  example "#{expr.inspect} stringifies as #{str}" do
10
16
  range = SemanticPuppet::VersionRange.parse(expr)
11
- expect(range.to_s).to eql str
17
+ expect(range.inspect).to eql str
12
18
  end
13
19
 
14
20
  includes.each do |vstring|
15
21
  example "#{expr.inspect} includes #{vstring}" do
16
22
  range = SemanticPuppet::VersionRange.parse(expr)
17
- expect(range).to include(SemanticPuppet::Version.parse(vstring))
23
+ expect(range).to cover(SemanticPuppet::Version.parse(vstring))
18
24
  end
19
25
 
20
26
  example "parse(#{expr.inspect}).to_s includes #{vstring}" do
21
27
  range = SemanticPuppet::VersionRange.parse(expr)
22
28
  range = SemanticPuppet::VersionRange.parse(range.to_s)
23
- expect(range).to include(SemanticPuppet::Version.parse(vstring))
29
+ expect(range).to cover(SemanticPuppet::Version.parse(vstring))
24
30
  end
25
31
  end
26
32
 
27
33
  excludes.each do |vstring|
28
34
  example "#{expr.inspect} excludes #{vstring}" do
29
35
  range = SemanticPuppet::VersionRange.parse(expr)
30
- expect(range).to_not include(SemanticPuppet::Version.parse(vstring))
36
+ expect(range).to_not cover(SemanticPuppet::Version.parse(vstring))
31
37
  end
32
38
 
33
39
  example "parse(#{expr.inspect}).to_s excludes #{vstring}" do
34
40
  range = SemanticPuppet::VersionRange.parse(expr)
35
41
  range = SemanticPuppet::VersionRange.parse(range.to_s)
36
- expect(range).to_not include(SemanticPuppet::Version.parse(vstring))
42
+ expect(range).to_not cover(SemanticPuppet::Version.parse(vstring))
37
43
  end
38
44
  end
39
45
  end
40
46
  end
41
47
 
42
48
  context 'loose version expressions' do
43
- expressions = {
49
+ test_expressions(
44
50
  [ '1.2.3-alpha' ] => {
45
51
  :to_str => '1.2.3-alpha',
46
52
  :includes => [ '1.2.3-alpha' ],
@@ -48,32 +54,28 @@ describe SemanticPuppet::VersionRange do
48
54
  },
49
55
  [ '1.2.3' ] => {
50
56
  :to_str => '1.2.3',
51
- :includes => [ '1.2.3-alpha', '1.2.3' ],
52
- :excludes => [ '1.2.2', '1.2.4-alpha' ],
57
+ :includes => [ '1.2.3' ],
58
+ :excludes => [ '1.2.2', '1.2.3-alpha', '1.2.4-alpha' ],
53
59
  },
54
60
  [ '1.2', '1.2.x', '1.2.X' ] => {
55
- :to_str => '1.2.x',
56
- :includes => [ '1.2.0-alpha', '1.2.0', '1.2.999' ],
57
- :excludes => [ '1.1.999', '1.3.0-0' ],
61
+ :to_str => '>=1.2.0 <1.3.0',
62
+ :includes => [ '1.2.0', '1.2.999' ],
63
+ :excludes => [ '1.1.999', '1.2.0-alpha', '1.3.0-0' ],
58
64
  },
59
65
  [ '1', '1.x', '1.X' ] => {
60
- :to_str => '1.x',
61
- :includes => [ '1.0.0-alpha', '1.999.0' ],
62
- :excludes => [ '0.999.999', '2.0.0-0' ],
66
+ :to_str => '>=1.0.0 <2.0.0',
67
+ :includes => [ '1.0.0', '1.999.0' ],
68
+ :excludes => [ '0.999.999', '1.0.0-alpha', '2.0.0-0' ],
63
69
  },
64
- }
65
-
66
- expressions.each do |range, vs|
67
- test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
68
- end
70
+ )
69
71
  end
70
72
 
71
73
  context 'open-ended expressions' do
72
- expressions = {
74
+ test_expressions(
73
75
  [ '>1.2.3', '> 1.2.3' ] => {
74
- :to_str => '>=1.2.4',
75
- :includes => [ '1.2.4-0', '999.0.0' ],
76
- :excludes => [ '1.2.3' ],
76
+ :to_str => '>1.2.3',
77
+ :includes => [ '999.0.0' ],
78
+ :excludes => [ '1.2.3', '1.2.4-0' ],
77
79
  },
78
80
  [ '>1.2.3-alpha', '> 1.2.3-alpha' ] => {
79
81
  :to_str => '>1.2.3-alpha',
@@ -83,87 +85,79 @@ describe SemanticPuppet::VersionRange do
83
85
 
84
86
  [ '>=1.2.3', '>= 1.2.3' ] => {
85
87
  :to_str => '>=1.2.3',
86
- :includes => [ '1.2.3-0', '999.0.0' ],
87
- :excludes => [ '1.2.2' ],
88
+ :includes => [ '999.0.0' ],
89
+ :excludes => [ '1.2.2', '1.2.3-0' ],
88
90
  },
89
91
  [ '>=1.2.3-alpha', '>= 1.2.3-alpha' ] => {
90
92
  :to_str => '>=1.2.3-alpha',
91
93
  :includes => [ '1.2.3-alpha', '1.2.3-alpha0', '999.0.0' ],
92
- :excludes => [ '1.2.3-alph' ],
94
+ :excludes => [ '1.2.3-alph', '1.2.4-alpha' ],
93
95
  },
94
96
 
95
97
  [ '<1.2.3', '< 1.2.3' ] => {
96
98
  :to_str => '<1.2.3',
97
- :includes => [ '0.0.0-0', '1.2.2' ],
98
- :excludes => [ '1.2.3-0', '2.0.0' ],
99
+ :includes => [ '0.0.0', '1.2.2' ],
100
+ :excludes => [ '0.0.0-0', '1.2.3-0', '2.0.0' ],
99
101
  },
100
102
  [ '<1.2.3-alpha', '< 1.2.3-alpha' ] => {
101
103
  :to_str => '<1.2.3-alpha',
102
- :includes => [ '0.0.0-0', '1.2.3-alph' ],
103
- :excludes => [ '1.2.3-alpha', '2.0.0' ],
104
+ :includes => [ '0.0.0', '1.2.3-alph' ],
105
+ :excludes => [ '0.0.0-0', '1.2.3-alpha', '2.0.0' ],
104
106
  },
105
107
 
106
108
  [ '<=1.2.3', '<= 1.2.3' ] => {
107
- :to_str => '<1.2.4',
108
- :includes => [ '0.0.0-0', '1.2.3' ],
109
- :excludes => [ '1.2.4-0' ],
109
+ :to_str => '<=1.2.3',
110
+ :includes => [ '0.0.0', '1.2.3' ],
111
+ :excludes => [ '0.0.0-0', '1.2.3-0' ],
110
112
  },
111
113
  [ '<=1.2.3-alpha', '<= 1.2.3-alpha' ] => {
112
114
  :to_str => '<=1.2.3-alpha',
113
- :includes => [ '0.0.0-0', '1.2.3-alpha' ],
114
- :excludes => [ '1.2.3-alpha0', '1.2.3-alpha.0', '1.2.3-alpha'.next ],
115
+ :includes => [ '0.0.0', '1.2.3-alpha' ],
116
+ :excludes => [ '0.0.0-0', '1.2.3-alpha0', '1.2.3-alpha.0', '1.2.3-alpha'.next ],
115
117
  },
116
- }
117
-
118
- expressions.each do |range, vs|
119
- test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
120
- end
118
+ )
121
119
  end
122
120
 
123
121
  context '"reasonably close" expressions' do
124
- expressions = {
122
+ test_expressions(
125
123
  [ '~ 1', '~1' ] => {
126
- :to_str => '1.x',
127
- :includes => [ '1.0.0-0', '1.999.999' ],
128
- :excludes => [ '0.999.999', '2.0.0-0' ],
124
+ :to_str => '>=1.0.0 <2.0.0',
125
+ :includes => [ '1.0.0', '1.999.999' ],
126
+ :excludes => [ '0.999.999', '1.0.0-0', '2.0.0-0' ],
129
127
  },
130
128
  [ '~ 1.2', '~1.2' ] => {
131
- :to_str => '1.2.x',
132
- :includes => [ '1.2.0-0', '1.2.999' ],
133
- :excludes => [ '1.1.999', '1.3.0-0' ],
129
+ :to_str => '>=1.2.0 <1.3.0',
130
+ :includes => [ '1.2.0', '1.2.999' ],
131
+ :excludes => [ '1.1.999', '1.2.0-0', '1.3.0-0' ],
134
132
  },
135
133
  [ '~ 1.2.3', '~1.2.3' ] => {
136
134
  :to_str => '>=1.2.3 <1.3.0',
137
- :includes => [ '1.2.3-0', '1.2.5' ],
138
- :excludes => [ '1.2.2', '1.3.0-0' ],
135
+ :includes => [ '1.2.3', '1.2.5' ],
136
+ :excludes => [ '1.2.2', '1.2.3-0', '1.3.0-0' ],
139
137
  },
140
138
  [ '~ 1.2.3-alpha', '~1.2.3-alpha' ] => {
141
- :to_str => '>=1.2.3-alpha <1.2.4',
139
+ :to_str => '>=1.2.3-alpha <1.3.0',
142
140
  :includes => [ '1.2.3-alpha', '1.2.3' ],
143
141
  :excludes => [ '1.2.3-alph', '1.2.4-0' ],
144
142
  },
145
- }
146
-
147
- expressions.each do |range, vs|
148
- test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
149
- end
143
+ )
150
144
  end
151
145
 
152
146
  context 'inclusive range expressions' do
153
- expressions = {
147
+ test_expressions(
154
148
  '1.2.3 - 1.3.4' => {
155
- :to_str => '>=1.2.3 <1.3.5',
156
- :includes => [ '1.2.3-0', '1.3.4' ],
157
- :excludes => [ '1.2.2', '1.3.5-0' ],
149
+ :to_str => '>=1.2.3 <=1.3.4',
150
+ :includes => [ '1.2.3', '1.3.4' ],
151
+ :excludes => [ '1.2.2', '1.2.3-0', '1.3.5-0' ],
158
152
  },
159
153
  '1.2.3 - 1.3.4-alpha' => {
160
154
  :to_str => '>=1.2.3 <=1.3.4-alpha',
161
- :includes => [ '1.2.3-0', '1.3.4-alpha' ],
162
- :excludes => [ '1.2.2', '1.3.4-alpha0', '1.3.5' ],
155
+ :includes => [ '1.2.3', '1.3.4-alpha' ],
156
+ :excludes => [ '1.2.2', '1.2.3-0', '1.3.4-alpha0', '1.3.5' ],
163
157
  },
164
158
 
165
159
  '1.2.3-alpha - 1.3.4' => {
166
- :to_str => '>=1.2.3-alpha <1.3.5',
160
+ :to_str => '>=1.2.3-alpha <=1.3.4',
167
161
  :includes => [ '1.2.3-alpha', '1.3.4' ],
168
162
  :excludes => [ '1.2.3-alph', '1.3.5-0' ],
169
163
  },
@@ -172,39 +166,109 @@ describe SemanticPuppet::VersionRange do
172
166
  :includes => [ '1.2.3-alpha', '1.3.4-alpha' ],
173
167
  :excludes => [ '1.2.3-alph', '1.3.4-alpha0', '1.3.5' ],
174
168
  },
175
- }
176
-
177
- expressions.each do |range, vs|
178
- test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
179
- end
169
+ )
180
170
  end
181
171
 
182
172
  context 'unioned expressions' do
183
- expressions = {
173
+ test_expressions(
184
174
  [ '1.2 <1.2.5' ] => {
185
175
  :to_str => '>=1.2.0 <1.2.5',
186
- :includes => [ '1.2.0-0', '1.2.4' ],
187
- :excludes => [ '1.1.999', '1.2.5-0', '1.9.0' ],
176
+ :includes => [ '1.2.0', '1.2.4' ],
177
+ :excludes => [ '1.1.999', '1.2.0-0', '1.2.5-0', '1.9.0' ],
188
178
  },
189
179
  [ '1 <=1.2.5' ] => {
190
- :to_str => '>=1.0.0 <1.2.6',
191
- :includes => [ '1.0.0-0', '1.2.5' ],
192
- :excludes => [ '0.999.999', '1.2.6-0', '1.9.0' ],
180
+ :to_str => '>=1.0.0 <=1.2.5',
181
+ :includes => [ '1.0.0', '1.2.5' ],
182
+ :excludes => [ '0.999.999', '1.0.0-0', '1.2.6-0', '1.9.0' ],
193
183
  },
194
184
  [ '>1.0.0 >2.0.0 >=3.0.0 <5.0.0' ] => {
195
185
  :to_str => '>=3.0.0 <5.0.0',
196
- :includes => [ '3.0.0-0', '4.999.999' ],
197
- :excludes => [ '2.999.999', '5.0.0-0' ],
186
+ :includes => [ '3.0.0', '4.999.999' ],
187
+ :excludes => [ '2.999.999', '3.0.0-0', '5.0.0-0' ],
198
188
  },
199
189
  [ '<1.0.0 >2.0.0' ] => {
200
190
  :to_str => '<0.0.0',
201
191
  :includes => [ ],
202
- :excludes => [ '0.0.0-0' ],
192
+ :excludes => [ '0.0.0-0', '0.0.0' ],
203
193
  },
204
- }
194
+ )
195
+ end
205
196
 
206
- expressions.each do |range, vs|
207
- test_range(range, vs[:to_str], vs[:includes], vs[:excludes])
197
+ context 'ored expressions' do
198
+ context 'overlapping' do
199
+ test_expressions(
200
+ [ '>=1.2.3 || 1.2.5' ] => {
201
+ :to_str => '>=1.2.3',
202
+ :includes => [ '1.2.3', '1.2.4' ],
203
+ :excludes => [ '1.2.3-0', '1.2.4-0' ],
204
+ },
205
+ [ '>=1.2.3 <=1.2.5 || >=1.2.5 <1.3.0' ] => {
206
+ :to_str => '>=1.2.3 <1.3.0',
207
+ :includes => [ '1.2.3', '1.2.6' ],
208
+ :excludes => [ '1.2.3-0', '1.2.6-0' ],
209
+ },
210
+ )
211
+ end
212
+
213
+ context 'adjacent' do
214
+ test_expressions(
215
+ [ '1.2.3 || 1.2.4 || 1.2.5' ] => {
216
+ :to_str => '>=1.2.3 <=1.2.5',
217
+ :includes => [ '1.2.3', '1.2.5' ],
218
+ :excludes => [ '1.2.3-0', '1.2.5-0' ],
219
+ },
220
+ [ '>=1.2.3 <1.2.5 || >=1.2.5 <1.3.0' ] => {
221
+ :to_str => '>=1.2.3 <1.3.0',
222
+ :includes => [ '1.2.3', '1.2.6' ],
223
+ :excludes => [ '1.2.3-0', '1.2.6-0' ],
224
+ },
225
+ )
226
+
227
+ let(:range) { SemanticPuppet::VersionRange.parse('>=1.2.3 <1.2.5 || >=1.2.5 <1.3.0') }
228
+
229
+ it 'returns expected begin' do
230
+ expect(range.begin.to_s).to eql('1.2.3')
231
+ end
232
+
233
+ it 'returns nil on end' do
234
+ expect(range.end.to_s).to eql('1.3.0')
235
+ end
236
+
237
+ it 'returns nil on exclude_begin?' do
238
+ expect(range.exclude_begin?).to be_falsey
239
+ end
240
+
241
+ it 'returns nil on exclude_end?' do
242
+ expect(range.exclude_end?).to be_truthy
243
+ end
244
+ end
245
+
246
+ context 'non-overlapping' do
247
+ test_expressions(
248
+ [ '1.2.3 || 1.2.5' ] => {
249
+ :to_str => '1.2.3 || 1.2.5',
250
+ :includes => [ '1.2.3', '1.2.5' ],
251
+ :excludes => [ '1.2.4', '1.2.3-0', '1.2.5-0' ],
252
+ },
253
+ )
254
+
255
+ let(:range) { SemanticPuppet::VersionRange.parse('1.2.3 || 1.2.5') }
256
+
257
+ it 'returns nil on begin' do
258
+ expect(range.begin).to be_nil
259
+ end
260
+
261
+ it 'returns nil on end' do
262
+ expect(range.end).to be_nil
263
+ end
264
+
265
+ it 'returns nil on exclude_begin?' do
266
+ expect(range.exclude_begin?).to be_nil
267
+ end
268
+
269
+ it 'returns nil on exclude_end?' do
270
+ expect(range.exclude_end?).to be_nil
271
+ end
208
272
  end
209
273
  end
210
274
 
@@ -304,4 +368,329 @@ describe SemanticPuppet::VersionRange do
304
368
  end
305
369
  end
306
370
 
371
+ context 'The version' do
372
+ def below(version, range)
373
+ version = SemanticPuppet::Version.parse(version)
374
+ range = SemanticPuppet::VersionRange.parse(range)
375
+ !range.include?(version) && range.ranges.all? { |part| part.exclude_begin? ? part.begin >= version : part.begin > version }
376
+ end
377
+
378
+ def above(version, range)
379
+ version = SemanticPuppet::Version.parse(version)
380
+ range = SemanticPuppet::VersionRange.parse(range)
381
+ !range.include?(version) && range.ranges.all? { |part| part.exclude_end? ? part.end <= version.to_stable : part.end < version.to_stable }
382
+ end
383
+
384
+ [
385
+ ['~1.2.2', '1.3.0'],
386
+ ['~0.6.1-1', '0.7.1-1'],
387
+ ['1.0.0 - 2.0.0', '2.0.1'],
388
+ ['1.0.0', '1.0.1-beta1'],
389
+ ['1.0.0', '2.0.0'],
390
+ ['<=2.0.0', '2.1.1'],
391
+ ['<=2.0.0', '3.2.9'],
392
+ ['<2.0.0', '2.0.0'],
393
+ ['0.1.20 || 1.2.4', '1.2.5'],
394
+ ['2.x.x', '3.0.0'],
395
+ ['1.2.x', '1.3.0'],
396
+ ['1.2.x || 2.x', '3.0.0'],
397
+ ['2.*.*', '5.0.1'],
398
+ ['1.2.*', '1.3.3'],
399
+ ['1.2.* || 2.*', '4.0.0'],
400
+ ['2', '3.0.0'],
401
+ ['2.3', '2.4.2'],
402
+ ['~2.4', '2.5.0'], # >=2.4.0 <2.5.0
403
+ ['~2.4', '2.5.5'],
404
+ ['~>3.2.1', '3.3.0'], # >=3.2.1 <3.3.0
405
+ ['~1', '2.2.3'], # >=1.0.0 <2.0.0
406
+ ['~>1', '2.2.4'],
407
+ ['~> 1', '3.2.3'],
408
+ ['~1.0', '1.1.2'], # >=1.0.0 <1.1.0
409
+ ['~ 1.0', '1.1.0'],
410
+ ['<1.2', '1.2.0'],
411
+ ['< 1.2', '1.2.1'],
412
+ ['1', '2.0.0-beta'],
413
+ ['~v0.5.4-pre', '0.6.0'],
414
+ ['~v0.5.4-pre', '0.6.1-pre'],
415
+ ['=0.7.x', '0.8.0'],
416
+ ['=0.7.x', '0.8.0-asdf'],
417
+ ['<0.7.x', '0.7.0'],
418
+ ['~1.2.2', '1.3.0'],
419
+ ['1.0.0 - 2.0.0', '2.2.3'],
420
+ ['1.0.0', '1.0.1'],
421
+ ['<=2.0.0', '3.0.0'],
422
+ ['<=2.0.0', '2.9999.9999'],
423
+ ['<=2.0.0', '2.2.9'],
424
+ ['<2.0.0', '2.9999.9999'],
425
+ ['<2.0.0', '2.2.9'],
426
+ ['2.x.x', '3.1.3'],
427
+ ['1.2.x', '1.3.3'],
428
+ ['1.2.x || 2.x', '3.1.3'],
429
+ ['2.*.*', '3.1.3'],
430
+ ['1.2.*', '1.3.3'],
431
+ ['1.2.* || 2.*', '3.1.3'],
432
+ ['2', '3.1.2'],
433
+ ['2.3', '2.4.1'],
434
+ ['~2.4', '2.5.0'], # >=2.4.0 <2.5.0
435
+ ['~>3.2.1', '3.3.2'], # >=3.2.1 <3.3.0
436
+ ['~1', '2.2.3'], # >=1.0.0 <2.0.0
437
+ ['~>1', '2.2.3'],
438
+ ['~1.0', '1.1.0'], # >=1.0.0 <1.1.0
439
+ ['<1', '1.0.0'],
440
+ ['1', '2.0.0-beta'],
441
+ ['<1', '1.0.0-beta'],
442
+ ['< 1', '1.0.0-beta'],
443
+ ['=0.7.x', '0.8.2'],
444
+ ['<0.7.x', '0.7.2']
445
+ ].each do |tuple|
446
+ it "#{tuple[1]} should be above range #{tuple[0]}" do
447
+ expect(above(tuple[1], tuple[0])).to be_truthy
448
+ end
449
+ end
450
+
451
+ [
452
+ ['~0.6.1-1', '0.6.1-1'],
453
+ ['1.0.0 - 2.0.0', '1.2.3'],
454
+ ['1.0.0 - 2.0.0', '0.9.9'],
455
+ ['1.0.0', '1.0.0'],
456
+ ['>=*', '0.2.4'],
457
+ ['', '1.0.0'],
458
+ ['*', '1.2.3'],
459
+ ['*', '1.2.3-foo'],
460
+ ['>=1.0.0', '1.0.0'],
461
+ ['>=1.0.0', '1.0.1'],
462
+ ['>=1.0.0', '1.1.0'],
463
+ ['>1.0.0', '1.0.1'],
464
+ ['>1.0.0', '1.1.0'],
465
+ ['<=2.0.0', '2.0.0'],
466
+ ['<=2.0.0', '1.9999.9999'],
467
+ ['<=2.0.0', '0.2.9'],
468
+ ['<2.0.0', '1.9999.9999'],
469
+ ['<2.0.0', '0.2.9'],
470
+ ['>= 1.0.0', '1.0.0'],
471
+ ['>= 1.0.0', '1.0.1'],
472
+ ['>= 1.0.0', '1.1.0'],
473
+ ['> 1.0.0', '1.0.1'],
474
+ ['> 1.0.0', '1.1.0'],
475
+ ['<= 2.0.0', '2.0.0'],
476
+ ['<= 2.0.0', '1.9999.9999'],
477
+ ['<= 2.0.0', '0.2.9'],
478
+ ['< 2.0.0', '1.9999.9999'],
479
+ ["<\t2.0.0", '0.2.9'],
480
+ ['>=0.1.97', '0.1.97'],
481
+ ['>=0.1.97', '0.1.97'],
482
+ ['0.1.20 || 1.2.4', '1.2.4'],
483
+ ['0.1.20 || >1.2.4', '1.2.4'],
484
+ ['0.1.20 || 1.2.4', '1.2.3'],
485
+ ['0.1.20 || 1.2.4', '0.1.20'],
486
+ ['>=0.2.3 || <0.0.1', '0.0.0'],
487
+ ['>=0.2.3 || <0.0.1', '0.2.3'],
488
+ ['>=0.2.3 || <0.0.1', '0.2.4'],
489
+ ['||', '1.3.4'],
490
+ ['2.x.x', '2.1.3'],
491
+ ['1.2.x', '1.2.3'],
492
+ ['1.2.x || 2.x', '2.1.3'],
493
+ ['1.2.x || 2.x', '1.2.3'],
494
+ ['x', '1.2.3'],
495
+ ['2.*.*', '2.1.3'],
496
+ ['1.2.*', '1.2.3'],
497
+ ['1.2.* || 2.*', '2.1.3'],
498
+ ['1.2.* || 2.*', '1.2.3'],
499
+ ['1.2.* || 2.*', '1.2.3'],
500
+ ['*', '1.2.3'],
501
+ ['2', '2.1.2'],
502
+ ['2.3', '2.3.1'],
503
+ ['~2.4', '2.4.0'], # >=2.4.0 <2.5.0
504
+ ['~2.4', '2.4.5'],
505
+ ['~>3.2.1', '3.2.2'], # >=3.2.1 <3.3.0
506
+ ['~1', '1.2.3'], # >=1.0.0 <2.0.0
507
+ ['~>1', '1.2.3'],
508
+ ['~> 1', '1.2.3'],
509
+ ['~1.0', '1.0.2'], # >=1.0.0 <1.1.0
510
+ ['~ 1.0', '1.0.2'],
511
+ ['>=1', '1.0.0'],
512
+ ['>= 1', '1.0.0'],
513
+ ['<1.2', '1.1.1'],
514
+ ['< 1.2', '1.1.1'],
515
+ ['1', '1.0.0-beta'],
516
+ ['~v0.5.4-pre', '0.5.5'],
517
+ ['~v0.5.4-pre', '0.5.4'],
518
+ ['=0.7.x', '0.7.2'],
519
+ ['>=0.7.x', '0.7.2'],
520
+ ['=0.7.x', '0.7.0-asdf'],
521
+ ['>=0.7.x', '0.7.0-asdf'],
522
+ ['<=0.7.x', '0.6.2'],
523
+ ['>0.2.3 >0.2.4 <=0.2.5', '0.2.5'],
524
+ ['>=0.2.3 <=0.2.4', '0.2.4'],
525
+ ['1.0.0 - 2.0.0', '2.0.0'],
526
+ ['^1', '0.0.0-0'],
527
+ ['^3.0.0', '2.0.0'],
528
+ ['^1.0.0 || ~2.0.1', '2.0.0'],
529
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '3.2.0'],
530
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '1.0.0-beta'],
531
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '5.0.0-0'],
532
+ ['^0.1.0 || ~3.0.1 || >4 <=5.0.0', '3.5.0']
533
+ ].each do |tuple|
534
+ it "#{tuple[1]} should not be above range #{tuple[0]}(#{SemanticPuppet::VersionRange.parse(tuple[0]).inspect})" do
535
+ expect(above(tuple[1], tuple[0])).to be_falsey
536
+ end
537
+ end
538
+
539
+ [
540
+ ['~1.2.2', '1.2.1'],
541
+ ['~0.6.1-1', '0.6.1-0'],
542
+ ['1.0.0 - 2.0.0', '0.0.1'],
543
+ ['1.0.0-beta.2', '1.0.0-beta.1'],
544
+ ['1.0.0', '0.0.0'],
545
+ ['>=2.0.0', '1.1.1'],
546
+ ['>=2.0.0', '1.2.9'],
547
+ ['>2.0.0', '2.0.0'],
548
+ ['0.1.20 || 1.2.4', '0.1.5'],
549
+ ['2.x.x', '1.0.0'],
550
+ ['1.2.x', '1.1.0'],
551
+ ['1.2.x || 2.x', '1.0.0'],
552
+ ['2.*.*', '1.0.1'],
553
+ ['1.2.*', '1.1.3'],
554
+ ['1.2.* || 2.*', '1.1.9999'],
555
+ ['2', '1.0.0'],
556
+ ['2.3', '2.2.2'],
557
+ ['~2.4', '2.3.0'], # >=2.4.0 <2.5.0
558
+ ['~2.4', '2.3.5'],
559
+ ['~>3.2.1', '3.2.0'], # >=3.2.1 <3.3.0
560
+ ['~1', '0.2.3'], # >=1.0.0 <2.0.0
561
+ ['~>1', '0.2.4'],
562
+ ['~> 1', '0.2.3'],
563
+ ['~1.0', '0.1.2'], # >=1.0.0 <1.1.0
564
+ ['~ 1.0', '0.1.0'],
565
+ ['>1.2', '1.2.0'],
566
+ ['> 1.2', '1.2.1'],
567
+ ['1', '0.0.0-beta'],
568
+ ['~v0.5.4-pre', '0.5.4-alpha'],
569
+ ['~v0.5.4-pre', '0.5.4-alpha'],
570
+ ['=0.7.x', '0.6.0'],
571
+ ['=0.7.x', '0.6.0-asdf'],
572
+ ['>=0.7.x', '0.6.0'],
573
+ ['~1.2.2', '1.2.1'],
574
+ ['1.0.0 - 2.0.0', '0.2.3'],
575
+ ['1.0.0', '0.0.1'],
576
+ ['>=2.0.0', '1.0.0'],
577
+ ['>=2.0.0', '1.9999.9999'],
578
+ ['>=2.0.0', '1.2.9'],
579
+ ['>2.0.0', '2.0.0'],
580
+ ['>2.0.0', '1.2.9'],
581
+ ['2.x.x', '1.1.3'],
582
+ ['1.2.x', '1.1.3'],
583
+ ['1.2.x || 2.x', '1.1.3'],
584
+ ['2.*.*', '1.1.3'],
585
+ ['1.2.*', '1.1.3'],
586
+ ['1.2.* || 2.*', '1.1.3'],
587
+ ['2', '1.9999.9999'],
588
+ ['2.3', '2.2.1'],
589
+ ['~2.4', '2.3.0'], # >=2.4.0 <2.5.0
590
+ ['~>3.2.1', '2.3.2'], # >=3.2.1 <3.3.0
591
+ ['~1', '0.2.3'], # >=1.0.0 <2.0.0
592
+ ['~>1', '0.2.3'],
593
+ ['~1.0', '0.0.0'], # >=1.0.0 <1.1.0
594
+ ['>1', '1.0.0'],
595
+ ['2', '1.0.0-beta'],
596
+ ['>1', '1.0.0-beta'],
597
+ ['> 1', '1.0.0-beta'],
598
+ ['=0.7.x', '0.6.2'],
599
+ ['=0.7.x', '0.7.0-asdf'],
600
+ ['^1', '1.0.0-0'],
601
+ ['>=0.7.x', '0.7.0-asdf'],
602
+ ['1', '1.0.0-beta'],
603
+ ['>=0.7.x', '0.6.2']
604
+ ].each do |tuple|
605
+ it "#{tuple[1]} should be below range #{tuple[0]}" do
606
+ expect(below(tuple[1], tuple[0])).to be_truthy
607
+ end
608
+ end
609
+
610
+ [
611
+ ['~ 1.0', '1.1.0'],
612
+ ['~0.6.1-1', '0.6.1-1'],
613
+ ['1.0.0 - 2.0.0', '1.2.3'],
614
+ ['1.0.0 - 2.0.0', '2.9.9'],
615
+ ['1.0.0', '1.0.0'],
616
+ ['>=*', '0.2.4'],
617
+ ['', '1.0.0'],
618
+ ['*', '1.2.3'],
619
+ ['>=1.0.0', '1.0.0'],
620
+ ['>=1.0.0', '1.0.1'],
621
+ ['>=1.0.0', '1.1.0'],
622
+ ['>1.0.0', '1.0.1'],
623
+ ['>1.0.0', '1.1.0'],
624
+ ['<=2.0.0', '2.0.0'],
625
+ ['<=2.0.0', '1.9999.9999'],
626
+ ['<=2.0.0', '0.2.9'],
627
+ ['<2.0.0', '1.9999.9999'],
628
+ ['<2.0.0', '0.2.9'],
629
+ ['>= 1.0.0', '1.0.0'],
630
+ ['>= 1.0.0', '1.0.1'],
631
+ ['>= 1.0.0', '1.1.0'],
632
+ ['> 1.0.0', '1.0.1'],
633
+ ['> 1.0.0', '1.1.0'],
634
+ ['<= 2.0.0', '2.0.0'],
635
+ ['<= 2.0.0', '1.9999.9999'],
636
+ ['<= 2.0.0', '0.2.9'],
637
+ ['< 2.0.0', '1.9999.9999'],
638
+ ["<\t2.0.0", '0.2.9'],
639
+ ['>=0.1.97', '0.1.97'],
640
+ ['0.1.20 || 1.2.4', '1.2.4'],
641
+ ['0.1.20 || >1.2.4', '1.2.4'],
642
+ ['0.1.20 || 1.2.4', '1.2.3'],
643
+ ['0.1.20 || 1.2.4', '0.1.20'],
644
+ ['>=0.2.3 || <0.0.1', '0.0.0'],
645
+ ['>=0.2.3 || <0.0.1', '0.2.3'],
646
+ ['>=0.2.3 || <0.0.1', '0.2.4'],
647
+ ['||', '1.3.4'],
648
+ ['2.x.x', '2.1.3'],
649
+ ['1.2.x', '1.2.3'],
650
+ ['1.2.x || 2.x', '2.1.3'],
651
+ ['1.2.x || 2.x', '1.2.3'],
652
+ ['x', '1.2.3'],
653
+ ['2.*.*', '2.1.3'],
654
+ ['1.2.*', '1.2.3'],
655
+ ['1.2.* || 2.*', '2.1.3'],
656
+ ['1.2.* || 2.*', '1.2.3'],
657
+ ['1.2.* || 2.*', '1.2.3'],
658
+ ['*', '1.2.3'],
659
+ ['2', '2.1.2'],
660
+ ['2.3', '2.3.1'],
661
+ ['~2.4', '2.4.0'], # >=2.4.0 <2.5.0
662
+ ['~2.4', '2.4.5'],
663
+ ['~>3.2.1', '3.2.2'], # >=3.2.1 <3.3.0
664
+ ['~1', '1.2.3'], # >=1.0.0 <2.0.0
665
+ ['~>1', '1.2.3'],
666
+ ['~> 1', '1.2.3'],
667
+ ['~1.0', '1.0.2'], # >=1.0.0 <1.1.0
668
+ ['~ 1.0', '1.0.2'],
669
+ ['>=1', '1.0.0'],
670
+ ['>= 1', '1.0.0'],
671
+ ['<1.2', '1.1.1'],
672
+ ['< 1.2', '1.1.1'],
673
+ ['~v0.5.4-pre', '0.5.5'],
674
+ ['~v0.5.4-pre', '0.5.4'],
675
+ ['=0.7.x', '0.7.2'],
676
+ ['>=0.7.x', '0.7.2'],
677
+ ['<=0.7.x', '0.6.2'],
678
+ ['>0.2.3 >0.2.4 <=0.2.5', '0.2.5'],
679
+ ['>=0.2.3 <=0.2.4', '0.2.4'],
680
+ ['1.0.0 - 2.0.0', '2.0.0'],
681
+ ['^3.0.0', '4.0.0'],
682
+ ['^1.0.0 || ~2.0.1', '2.0.0'],
683
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '3.2.0'],
684
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '1.0.0-beta'],
685
+ ['^0.1.0 || ~3.0.1 || 5.0.0', '5.0.0-0'],
686
+ ['^0.1.0 || ~3.0.1 || >4 <=5.0.0', '3.5.0'],
687
+ ['^1.0.0-alpha', '1.0.0-beta'],
688
+ ['~1.0.0-alpha', '1.0.0-beta'],
689
+ ['=0.1.0', '1.0.0']
690
+ ].each do |tuple|
691
+ it "#{tuple[1]} should not be below range #{tuple[0]}" do
692
+ expect(below(tuple[1], tuple[0])).to be_falsey
693
+ end
694
+ end
695
+ end
307
696
  end