semantic_puppet 0.1.3 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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