solve 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,306 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Solutions when using the ruby solver" do
4
-
5
- before do
6
- Solve.engine = :ruby
7
- end
8
-
9
- it "chooses the correct artifact for the demands" do
10
- graph = Solve::Graph.new
11
- graph.artifact("mysql", "2.0.0")
12
- graph.artifact("mysql", "1.2.0")
13
- graph.artifact("nginx", "1.0.0").depends("mysql", "= 1.2.0")
14
-
15
- result = Solve.it!(graph, [["nginx", "= 1.0.0"], ["mysql"]])
16
-
17
- result.should eql("nginx" => "1.0.0", "mysql" => "1.2.0")
18
- end
19
-
20
- it "chooses the best artifact for the demands" do
21
- graph = Solve::Graph.new
22
- graph.artifact("mysql", "2.0.0")
23
- graph.artifact("mysql", "1.2.0")
24
- graph.artifact("nginx", "1.0.0").depends("mysql", ">= 1.2.0")
25
-
26
- result = Solve.it!(graph, [["nginx", "= 1.0.0"], ["mysql"]])
27
-
28
- result.should eql("nginx" => "1.0.0", "mysql" => "2.0.0")
29
- end
30
-
31
- it "raises NoSolutionError when a solution cannot be found" do
32
- graph = Solve::Graph.new
33
- graph.artifact("mysql", "1.2.0")
34
-
35
- lambda {
36
- Solve.it!(graph, ["mysql", ">= 2.0.0"])
37
- }.should raise_error(Solve::Errors::NoSolutionError)
38
- end
39
-
40
- it "find the correct solution when backtracking in variables introduced via demands" do
41
- graph = Solve::Graph.new
42
-
43
- graph.artifact("D", "1.2.0")
44
- graph.artifact("D", "1.3.0")
45
- graph.artifact("D", "1.4.0")
46
- graph.artifact("D", "2.0.0")
47
- graph.artifact("D", "2.1.0")
48
-
49
- graph.artifact("C", "2.0.0").depends("D", "= 1.2.0")
50
- graph.artifact("C", "2.1.0").depends("D", ">= 2.1.0")
51
- graph.artifact("C", "2.2.0").depends("D", "> 2.0.0")
52
-
53
- graph.artifact("B", "1.0.0").depends("D", "= 1.0.0")
54
- graph.artifact("B", "1.1.0").depends("D", "= 1.0.0")
55
- graph.artifact("B", "2.0.0").depends("D", ">= 1.3.0")
56
- graph.artifact("B", "2.1.0").depends("D", ">= 2.0.0")
57
-
58
- graph.artifact("A", "1.0.0").depends("B", "> 2.0.0")
59
- graph.artifact("A", "1.0.0").depends("C", "= 2.1.0")
60
- graph.artifact("A", "1.0.1").depends("B", "> 1.0.0")
61
- graph.artifact("A", "1.0.1").depends("C", "= 2.1.0")
62
- graph.artifact("A", "1.0.2").depends("B", "> 1.0.0")
63
- graph.artifact("A", "1.0.2").depends("C", "= 2.0.0")
64
-
65
- result = Solve.it!(graph, [["A", "~> 1.0.0"], ["D", ">= 2.0.0"]])
66
-
67
- result.should eql("A" => "1.0.1",
68
- "B" => "2.1.0",
69
- "C" => "2.1.0",
70
- "D" => "2.1.0")
71
- end
72
-
73
- it "rejects a circular dependency with a circular dep error" do
74
- graph = Solve::Graph.new
75
-
76
- graph.artifact("A", "1.0.0").depends("B", "1.0.0")
77
- graph.artifact("B", "1.0.0").depends("C", "1.0.0")
78
- graph.artifact("C", "1.0.0").depends("A", "1.0.0")
79
-
80
- expect { Solve.it!(graph, [["A", "1.0.0"]]) }.to raise_error(Solve::Errors::NoSolutionError)
81
- end
82
-
83
- it "rejects a p shaped depenency chain with a circular dep error" do
84
- graph = Solve::Graph.new
85
-
86
- graph.artifact("A", "1.0.0").depends("B", "1.0.0")
87
- graph.artifact("B", "1.0.0").depends("C", "1.0.0")
88
- graph.artifact("C", "1.0.0").depends("B", "1.0.0")
89
-
90
- expect { Solve.it!(graph, [["A", "1.0.0"]]) }.to raise_error(Solve::Errors::NoSolutionError)
91
- end
92
-
93
- it "finds the correct solution when there is a diamond shaped dependency" do
94
- graph = Solve::Graph.new
95
-
96
- graph.artifact("A", "1.0.0")
97
- .depends("B", "1.0.0")
98
- .depends("C", "1.0.0")
99
- graph.artifact("B", "1.0.0")
100
- .depends("D", "1.0.0")
101
- graph.artifact("C", "1.0.0")
102
- .depends("D", "1.0.0")
103
- graph.artifact("D", "1.0.0")
104
-
105
- result = Solve.it!(graph, [["A", "1.0.0"]])
106
-
107
- result.should eql("A" => "1.0.0",
108
- "B" => "1.0.0",
109
- "C" => "1.0.0",
110
- "D" => "1.0.0")
111
- end
112
-
113
- it "solves when packages and constraints have prerelease elements" do
114
- graph = Solve::Graph.new
115
-
116
- graph.artifact("A", "1.0.0")
117
- .depends("B", ">= 1.0.0-alpha")
118
- graph.artifact("B", "1.0.0-alpha")
119
- .depends("C", "1.0.0")
120
- graph.artifact("C", "1.0.0")
121
-
122
- result = Solve.it!(graph, [["A", "1.0.0"]])
123
-
124
- result.should eql("A" => "1.0.0",
125
- "B" => "1.0.0-alpha",
126
- "C" => "1.0.0")
127
-
128
- end
129
-
130
- it "solves when packages and constraints have build elements" do
131
- graph = Solve::Graph.new
132
-
133
- graph.artifact("A", "1.0.0")
134
- .depends("B", ">= 1.0.0+build")
135
- graph.artifact("B", "1.0.0+build")
136
- .depends("C", "1.0.0")
137
- graph.artifact("C", "1.0.0")
138
-
139
- result = Solve.it!(graph, [["A", "1.0.0"]])
140
-
141
- result.should eql("A" => "1.0.0",
142
- "B" => "1.0.0+build",
143
- "C" => "1.0.0")
144
-
145
- end
146
-
147
- it "fails with a self dependency" do
148
- graph = Solve::Graph.new
149
-
150
- graph.artifact("bottom", "1.0.0")
151
- graph.artifact("middle", "1.0.0").depends("top", "= 1.0.0").depends("middle")
152
-
153
- demands = [["bottom", "1.0.0"], ["middle", "1.0.0"]]
154
-
155
- expect { Solve.it!(graph, demands, { :sorted => true } ) }.to raise_error { |error|
156
- error.should be_a(Solve::Errors::NoSolutionError)
157
- }
158
- end
159
-
160
- it "gives an empty solution when there are no demands" do
161
- graph = Solve::Graph.new
162
- result = Solve.it!(graph, [])
163
- result.should eql({})
164
- end
165
-
166
- it "tries all combinations until it finds a solution" do
167
-
168
- graph = Solve::Graph.new
169
-
170
- graph.artifact("A", "1.0.0").depends("B", "~> 1.0.0")
171
- graph.artifact("A", "1.0.1").depends("B", "~> 1.0.0")
172
- graph.artifact("A", "1.0.2").depends("B", "~> 1.0.0")
173
-
174
- graph.artifact("B", "1.0.0").depends("C", "~> 1.0.0")
175
- graph.artifact("B", "1.0.1").depends("C", "~> 1.0.0")
176
- graph.artifact("B", "1.0.2").depends("C", "~> 1.0.0")
177
-
178
- graph.artifact("C", "1.0.0").depends("D", "1.0.0")
179
- graph.artifact("C", "1.0.1").depends("D", "1.0.0")
180
- graph.artifact("C", "1.0.2").depends("D", "1.0.0")
181
-
182
- # Note:
183
- # This test previously used two circular dependencies:
184
- # (D 1.0.0) -> A < 0.0.0
185
- # (D 0.0.0) -> A = 0.0.0
186
- # But Molinillo doesn't support circular dependencies at all.
187
-
188
- # ensure we can't find a solution in the above
189
- graph.artifact("D", "1.0.0").depends("E", "< 0.0.0")
190
-
191
- # Add a solution to the graph that should be reached only after all of the
192
- # others have been tried
193
- graph.artifact("A", "0.0.0").depends("B", "0.0.0")
194
- graph.artifact("B", "0.0.0").depends("C", "0.0.0")
195
- graph.artifact("C", "0.0.0").depends("D", "0.0.0")
196
- graph.artifact("D", "0.0.0")
197
-
198
- demands = [["A"]]
199
-
200
- result = Solve.it!(graph, demands)
201
-
202
- result.should eql({ "A" => "0.0.0",
203
- "B" => "0.0.0",
204
- "C" => "0.0.0",
205
- "D" => "0.0.0" })
206
-
207
- end
208
-
209
- it "correctly resolves when a resolution exists but it is not the latest" do
210
- graph = Solve::Graph.new
211
-
212
- graph.artifact("get-the-old-one", "1.0.0")
213
- .depends("locked-mid-1", ">= 0.0.0")
214
- .depends("locked-mid-2", ">= 0.0.0")
215
- graph.artifact("get-the-old-one", "0.5.0")
216
-
217
- graph.artifact("locked-mid-1", "2.0.0").depends("old-bottom", "= 2.0.0")
218
- graph.artifact("locked-mid-1", "1.3.0").depends("old-bottom", "= 0.5.0")
219
- graph.artifact("locked-mid-1", "1.0.0")
220
-
221
- graph.artifact("locked-mid-2", "2.0.0").depends("old-bottom", "= 2.1.0")
222
- graph.artifact("locked-mid-2", "1.4.0").depends("old-bottom", "= 0.5.0")
223
- graph.artifact("locked-mid-2", "1.0.0")
224
-
225
- graph.artifact("old-bottom", "2.1.0")
226
- graph.artifact("old-bottom", "2.0.0")
227
- graph.artifact("old-bottom", "1.0.0")
228
- graph.artifact("old-bottom", "0.5.0")
229
-
230
- demands = [["get-the-old-one"]]
231
-
232
- result = Solve.it!(graph, demands)
233
-
234
- # Note: Gecode solver is different. It picks:
235
- #
236
- # "get-the-old-one" => "1.0.0",
237
- # "locked-mid-1" => "1.0.0",
238
- # "locked-mid-2" => "2.0.0",
239
- # "old-bottom" => "2.1.0"
240
-
241
- result.should eql({
242
- "get-the-old-one" => "1.0.0",
243
- "locked-mid-1" => "2.0.0",
244
- "locked-mid-2" => "1.0.0",
245
- "old-bottom" => "2.0.0",
246
- })
247
- end
248
-
249
- describe "when options[:sorted] is true" do
250
- describe "with a simple list of dependencies" do
251
- it "returns a sorted list of dependencies" do
252
- graph = Solve::Graph.new
253
-
254
- graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
255
- graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
256
- graph.artifact("C", "1.0.0")
257
-
258
- demands = [["A"]]
259
-
260
- result = Solve.it!(graph, demands, { :sorted => true })
261
-
262
- result.should eql([
263
- ["C", "1.0.0"],
264
- ["B", "1.0.0"],
265
- ["A", "1.0.0"],
266
- ])
267
- end
268
- end
269
-
270
- # The order that the demands come in determines the order of artifacts
271
- # in the solver's variable_table. This must not determine the sort order
272
- describe "with a constraint that depends upon an earlier constrained artifact" do
273
- it "returns a sorted list of dependencies" do
274
- graph = Solve::Graph.new
275
-
276
- graph.artifact("B", "1.0.0").depends("A", "= 1.0.0")
277
- graph.artifact("A", "1.0.0").depends("C", "= 1.0.0")
278
- graph.artifact("C", "1.0.0")
279
-
280
- demands = [["A"], ["B"]]
281
-
282
- result = Solve.it!(graph, demands, { :sorted => true } )
283
-
284
- result.should eql([
285
- ["C", "1.0.0"],
286
- ["A", "1.0.0"],
287
- ["B", "1.0.0"],
288
- ])
289
- end
290
- end
291
-
292
- describe "when the solution is cyclic" do
293
- it "raises a Solve::Errors::NoSolutionError because Molinillo doesn't support circular deps" do
294
- graph = Solve::Graph.new
295
-
296
- graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
297
- graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
298
- graph.artifact("C", "1.0.0").depends("A", "= 1.0.0")
299
-
300
- demands = [["A"]]
301
-
302
- expect { Solve.it!(graph, demands, { :sorted => true } ) }.to raise_error(Solve::Errors::NoSolutionError)
303
- end
304
- end
305
- end
306
- end
@@ -1,316 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "Solutions", :gecode do
4
-
5
- before do
6
- Solve.engine = :gecode
7
- end
8
-
9
- it "chooses the correct artifact for the demands" do
10
- graph = Solve::Graph.new
11
- graph.artifact("mysql", "2.0.0")
12
- graph.artifact("mysql", "1.2.0")
13
- graph.artifact("nginx", "1.0.0").depends("mysql", "= 1.2.0")
14
-
15
- result = Solve.it!(graph, [["nginx", "= 1.0.0"], ["mysql"]])
16
-
17
- result.should eql("nginx" => "1.0.0", "mysql" => "1.2.0")
18
- end
19
-
20
- it "chooses the best artifact for the demands" do
21
- graph = Solve::Graph.new
22
- graph.artifact("mysql", "2.0.0")
23
- graph.artifact("mysql", "1.2.0")
24
- graph.artifact("nginx", "1.0.0").depends("mysql", ">= 1.2.0")
25
-
26
- result = Solve.it!(graph, [["nginx", "= 1.0.0"], ["mysql"]])
27
-
28
- result.should eql("nginx" => "1.0.0", "mysql" => "2.0.0")
29
- end
30
-
31
- it "raises NoSolutionError when a solution cannot be found" do
32
- graph = Solve::Graph.new
33
- graph.artifact("mysql", "1.2.0")
34
-
35
- lambda {
36
- Solve.it!(graph, ["mysql", ">= 2.0.0"])
37
- }.should raise_error(Solve::Errors::NoSolutionError)
38
- end
39
-
40
- it "find the correct solution when backtracking in variables introduced via demands" do
41
- graph = Solve::Graph.new
42
-
43
- graph.artifact("D", "1.2.0")
44
- graph.artifact("D", "1.3.0")
45
- graph.artifact("D", "1.4.0")
46
- graph.artifact("D", "2.0.0")
47
- graph.artifact("D", "2.1.0")
48
-
49
- graph.artifact("C", "2.0.0").depends("D", "= 1.2.0")
50
- graph.artifact("C", "2.1.0").depends("D", ">= 2.1.0")
51
- graph.artifact("C", "2.2.0").depends("D", "> 2.0.0")
52
-
53
- graph.artifact("B", "1.0.0").depends("D", "= 1.0.0")
54
- graph.artifact("B", "1.1.0").depends("D", "= 1.0.0")
55
- graph.artifact("B", "2.0.0").depends("D", ">= 1.3.0")
56
- graph.artifact("B", "2.1.0").depends("D", ">= 2.0.0")
57
-
58
- graph.artifact("A", "1.0.0").depends("B", "> 2.0.0")
59
- graph.artifact("A", "1.0.0").depends("C", "= 2.1.0")
60
- graph.artifact("A", "1.0.1").depends("B", "> 1.0.0")
61
- graph.artifact("A", "1.0.1").depends("C", "= 2.1.0")
62
- graph.artifact("A", "1.0.2").depends("B", "> 1.0.0")
63
- graph.artifact("A", "1.0.2").depends("C", "= 2.0.0")
64
-
65
- result = Solve.it!(graph, [["A", "~> 1.0.0"], ["D", ">= 2.0.0"]])
66
-
67
- result.should eql("A" => "1.0.1",
68
- "B" => "2.1.0",
69
- "C" => "2.1.0",
70
- "D" => "2.1.0")
71
- end
72
-
73
- it "finds the correct solution when there is a circular dependency" do
74
- graph = Solve::Graph.new
75
-
76
- graph.artifact("A", "1.0.0").depends("B", "1.0.0")
77
- graph.artifact("B", "1.0.0").depends("C", "1.0.0")
78
- graph.artifact("C", "1.0.0").depends("A", "1.0.0")
79
-
80
- result = Solve.it!(graph, [["A", "1.0.0"]])
81
-
82
- result.should eql("A" => "1.0.0",
83
- "B" => "1.0.0",
84
- "C" => "1.0.0")
85
- end
86
-
87
- it "finds the correct solution when there is a p shaped depenency chain" do
88
- graph = Solve::Graph.new
89
-
90
- graph.artifact("A", "1.0.0").depends("B", "1.0.0")
91
- graph.artifact("B", "1.0.0").depends("C", "1.0.0")
92
- graph.artifact("C", "1.0.0").depends("B", "1.0.0")
93
-
94
- result = Solve.it!(graph, [["A", "1.0.0"]])
95
-
96
- result.should eql("A" => "1.0.0",
97
- "B" => "1.0.0",
98
- "C" => "1.0.0")
99
- end
100
-
101
- it "finds the correct solution when there is a diamond shaped dependency" do
102
- graph = Solve::Graph.new
103
-
104
- graph.artifact("A", "1.0.0")
105
- .depends("B", "1.0.0")
106
- .depends("C", "1.0.0")
107
- graph.artifact("B", "1.0.0")
108
- .depends("D", "1.0.0")
109
- graph.artifact("C", "1.0.0")
110
- .depends("D", "1.0.0")
111
- graph.artifact("D", "1.0.0")
112
-
113
- result = Solve.it!(graph, [["A", "1.0.0"]])
114
-
115
- result.should eql("A" => "1.0.0",
116
- "B" => "1.0.0",
117
- "C" => "1.0.0",
118
- "D" => "1.0.0")
119
- end
120
-
121
- it "solves when packages and constraints have prerelease elements" do
122
- graph = Solve::Graph.new
123
-
124
- graph.artifact("A", "1.0.0")
125
- .depends("B", ">= 1.0.0-alpha")
126
- graph.artifact("B", "1.0.0-alpha")
127
- .depends("C", "1.0.0")
128
- graph.artifact("C", "1.0.0")
129
-
130
- result = Solve.it!(graph, [["A", "1.0.0"]])
131
-
132
- result.should eql("A" => "1.0.0",
133
- "B" => "1.0.0-alpha",
134
- "C" => "1.0.0")
135
-
136
- end
137
-
138
- it "solves when packages and constraints have build elements" do
139
- graph = Solve::Graph.new
140
-
141
- graph.artifact("A", "1.0.0")
142
- .depends("B", ">= 1.0.0+build")
143
- graph.artifact("B", "1.0.0+build")
144
- .depends("C", "1.0.0")
145
- graph.artifact("C", "1.0.0")
146
-
147
- result = Solve.it!(graph, [["A", "1.0.0"]])
148
-
149
- result.should eql("A" => "1.0.0",
150
- "B" => "1.0.0+build",
151
- "C" => "1.0.0")
152
-
153
- end
154
-
155
- it "fails with a self dependency" do
156
- graph = Solve::Graph.new
157
-
158
- graph.artifact("bottom", "1.0.0")
159
- graph.artifact("middle", "1.0.0").depends("top", "= 1.0.0").depends("middle")
160
-
161
- demands = [["bottom", "1.0.0"], ["middle", "1.0.0"]]
162
-
163
- expect { Solve.it!(graph, demands, { :sorted => true } ) }.to raise_error { |error|
164
- error.should be_a(Solve::Errors::NoSolutionError)
165
- }
166
- end
167
-
168
- it "gives an empty solution when there are no demands" do
169
- graph = Solve::Graph.new
170
- result = Solve.it!(graph, [])
171
- result.should eql({})
172
- end
173
-
174
- it "tries all combinations until it finds a solution" do
175
-
176
- graph = Solve::Graph.new
177
-
178
- graph.artifact("A", "1.0.0").depends("B", "~> 1.0.0")
179
- graph.artifact("A", "1.0.1").depends("B", "~> 1.0.0")
180
- graph.artifact("A", "1.0.2").depends("B", "~> 1.0.0")
181
-
182
- graph.artifact("B", "1.0.0").depends("C", "~> 1.0.0")
183
- graph.artifact("B", "1.0.1").depends("C", "~> 1.0.0")
184
- graph.artifact("B", "1.0.2").depends("C", "~> 1.0.0")
185
-
186
- graph.artifact("C", "1.0.0").depends("D", "1.0.0")
187
- graph.artifact("C", "1.0.1").depends("D", "1.0.0")
188
- graph.artifact("C", "1.0.2").depends("D", "1.0.0")
189
-
190
- # ensure we can't find a solution in the above
191
- graph.artifact("D", "1.0.0").depends("A", "< 0.0.0")
192
-
193
- # Add a solution to the graph that should be reached only after
194
- # all of the others have been tried
195
- # it must be circular to ensure that no other branch can find it
196
- graph.artifact("A", "0.0.0").depends("B", "0.0.0")
197
- graph.artifact("B", "0.0.0").depends("C", "0.0.0")
198
- graph.artifact("C", "0.0.0").depends("D", "0.0.0")
199
- graph.artifact("D", "0.0.0").depends("A", "0.0.0")
200
-
201
- demands = [["A"]]
202
-
203
- result = Solve.it!(graph, demands)
204
-
205
- result.should eql({ "A" => "0.0.0",
206
- "B" => "0.0.0",
207
- "C" => "0.0.0",
208
- "D" => "0.0.0" })
209
-
210
- end
211
-
212
- it "correctly resolves when a resolution exists but it is not the latest" do
213
- graph = Solve::Graph.new
214
-
215
- graph.artifact("get-the-old-one", "1.0.0")
216
- .depends("locked-mid-1", ">= 0.0.0")
217
- .depends("locked-mid-2", ">= 0.0.0")
218
- graph.artifact("get-the-old-one", "0.5.0")
219
-
220
- graph.artifact("locked-mid-1", "2.0.0").depends("old-bottom", "= 2.0.0")
221
- graph.artifact("locked-mid-1", "1.3.0").depends("old-bottom", "= 0.5.0")
222
- graph.artifact("locked-mid-1", "1.0.0")
223
-
224
- graph.artifact("locked-mid-2", "2.0.0").depends("old-bottom", "= 2.1.0")
225
- graph.artifact("locked-mid-2", "1.4.0").depends("old-bottom", "= 0.5.0")
226
- graph.artifact("locked-mid-2", "1.0.0")
227
-
228
- graph.artifact("old-bottom", "2.1.0")
229
- graph.artifact("old-bottom", "2.0.0")
230
- graph.artifact("old-bottom", "1.0.0")
231
- graph.artifact("old-bottom", "0.5.0")
232
-
233
- demands = [["get-the-old-one"]]
234
-
235
- result = Solve.it!(graph, demands)
236
-
237
- # ruby solver result:
238
- #
239
- # "get-the-old-one" => "1.0.0",
240
- # "locked-mid-1" => "2.0.0",
241
- # "locked-mid-2" => "1.0.0",
242
- # "old-bottom" => "2.0.0"
243
-
244
- result.should eql({
245
- "get-the-old-one" => "1.0.0",
246
- "locked-mid-1" => "1.0.0",
247
- "locked-mid-2" => "2.0.0",
248
- "old-bottom" => "2.1.0",
249
- })
250
- end
251
-
252
- describe "when options[:sorted] is true" do
253
- describe "with a simple list of dependencies" do
254
- it "returns a sorted list of dependencies" do
255
- graph = Solve::Graph.new
256
-
257
- graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
258
- graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
259
- graph.artifact("C", "1.0.0")
260
-
261
- demands = [["A"]]
262
-
263
- result = Solve.it!(graph, demands, { :sorted => true })
264
-
265
- result.should eql([
266
- ["C", "1.0.0"],
267
- ["B", "1.0.0"],
268
- ["A", "1.0.0"],
269
- ])
270
- end
271
- end
272
-
273
- # The order that the demands come in determines the order of artifacts
274
- # in the solver's variable_table. This must not determine the sort order
275
- describe "with a constraint that depends upon an earlier constrained artifact" do
276
- it "returns a sorted list of dependencies" do
277
- graph = Solve::Graph.new
278
-
279
- graph.artifact("B", "1.0.0").depends("A", "= 1.0.0")
280
- graph.artifact("A", "1.0.0").depends("C", "= 1.0.0")
281
- graph.artifact("C", "1.0.0")
282
-
283
- demands = [["A"], ["B"]]
284
-
285
- result = Solve.it!(graph, demands, { :sorted => true } )
286
-
287
- result.should eql([
288
- ["C", "1.0.0"],
289
- ["A", "1.0.0"],
290
- ["B", "1.0.0"],
291
- ])
292
- end
293
- end
294
-
295
- describe "when the solution is cyclic" do
296
- it "raises a Solve::Errors::UnsortableSolutionError which contains the unsorted solution" do
297
- graph = Solve::Graph.new
298
-
299
- graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
300
- graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
301
- graph.artifact("C", "1.0.0").depends("A", "= 1.0.0")
302
-
303
- demands = [["A"]]
304
-
305
- expect { Solve.it!(graph, demands, { :sorted => true } ) }.to raise_error { |error|
306
- error.should be_a(Solve::Errors::UnsortableSolutionError)
307
- error.unsorted_solution.should eql({
308
- "A" => "1.0.0",
309
- "B" => "1.0.0",
310
- "C" => "1.0.0",
311
- })
312
- }
313
- end
314
- end
315
- end
316
- end