solve 1.2.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Solutions" do
3
+ describe "Solutions", :gecode do
4
+
5
+ before do
6
+ Solve.engine = :gecode
7
+ end
8
+
4
9
  it "chooses the correct artifact for the demands" do
5
10
  graph = Solve::Graph.new
6
11
  graph.artifact("mysql", "2.0.0")
@@ -1,12 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Solve::Solver do
3
+ require 'solve/gecode_solver'
4
+
5
+ describe Solve::GecodeSolver, :gecode do
6
+
7
+ before(:all) do
8
+ described_class.activate
9
+ end
10
+
4
11
  describe "ClassMethods" do
5
12
  describe "::timeout" do
6
13
  subject { described_class.timeout }
7
14
 
8
- it "returns 10,000 by default" do
9
- expect(subject).to eql(10_000)
15
+ it "returns 30,000 by default" do
16
+ expect(subject).to eql(30_000)
10
17
  end
11
18
 
12
19
  context "when the SOLVE_TIMEOUT env variable is set" do
@@ -17,6 +24,28 @@ describe Solve::Solver do
17
24
  end
18
25
  end
19
26
  end
27
+
28
+ describe "::activate" do
29
+
30
+ context "when dep_selector is not installed" do
31
+
32
+ it "raises EngineNotAvailable" do
33
+ exception = LoadError.new("cannot load such file -- dep_selector")
34
+ allow(described_class).to receive(:require).with("dep_selector").and_raise(exception)
35
+ expect { described_class.activate }.to raise_error(Solve::Errors::EngineNotAvailable)
36
+ end
37
+
38
+ end
39
+
40
+ context "when dep_selector is installed" do
41
+
42
+ it "requires dep_selector" do
43
+ expect(described_class).to receive(:require).with("dep_selector").and_call_original
44
+ described_class.activate
45
+ end
46
+ end
47
+
48
+ end
20
49
  end
21
50
 
22
51
  let(:graph) { double(Solve::Graph) }
@@ -162,7 +191,8 @@ describe Solve::Solver do
162
191
  end
163
192
 
164
193
  it "implements the required interface" do
165
- json_string = serializer.serialize(solver)
194
+ problem = Solve::Problem.from_solver(solver)
195
+ json_string = serializer.serialize(problem)
166
196
  problem_data = JSON.parse(json_string)
167
197
  expected_demands = [
168
198
  {"name" => "mysql", "constraint" => ">= 0.0.0"},
@@ -0,0 +1,166 @@
1
+ require 'spec_helper'
2
+
3
+ describe Solve::RubySolver do
4
+ describe "ClassMethods" do
5
+ describe "::timeout" do
6
+ subject { described_class.timeout }
7
+
8
+ it "returns 30,000 by default" do
9
+ expect(subject).to eql(30_000)
10
+ end
11
+
12
+ context "when the SOLVE_TIMEOUT env variable is set" do
13
+ before { ENV.stub(:[]).with("SOLVE_TIMEOUT") { "30" } }
14
+
15
+ it "returns the value multiplied by a thousand" do
16
+ expect(subject).to eql(30_000)
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "::activate" do
22
+
23
+ it "is a no-op" do
24
+ described_class.activate
25
+ end
26
+
27
+ end
28
+ end
29
+
30
+ let(:graph) { double(Solve::Graph) }
31
+ let(:demands) { [["mysql"], ["nginx"]] }
32
+ subject(:solver) { described_class.new(graph, demands, dependency_source: "Berksfile") }
33
+
34
+ it "has a list of demands as ruby literals" do
35
+ solver.demands_array.should == demands
36
+ end
37
+
38
+ it "has a list of demands as model objects" do
39
+ expected = [
40
+ Solve::Demand.new(solver, "mysql"),
41
+ Solve::Demand.new(solver, "nginx")
42
+ ]
43
+ solver.demands.should == expected
44
+ end
45
+
46
+ it "has a graph" do
47
+ solver.graph.should == graph
48
+ end
49
+
50
+ describe "when the constraints are solvable" do
51
+ let(:graph) do
52
+ graph = Solve::Graph.new
53
+ graph.artifact("A", "1.0.0")
54
+ graph.artifact("B", "1.0.0").depends("A")
55
+ graph
56
+ end
57
+
58
+ let(:demands) { [["A"], ["B"]] }
59
+
60
+ it "gives the solution as a Hash" do
61
+ solver.resolve.should == {"A"=>"1.0.0", "B"=>"1.0.0"}
62
+ end
63
+
64
+ it "gives the solution in sorted form" do
65
+ solver.resolve(sorted: true).should == [["A", "1.0.0"], ["B", "1.0.0"]]
66
+ end
67
+ end
68
+
69
+ describe "when the constraints are not solvable" do
70
+ let(:error) do
71
+ begin
72
+ solver.resolve
73
+ rescue => e
74
+ e
75
+ else
76
+ raise "Expected resolve to cause an error"
77
+ end
78
+ end
79
+
80
+ context "and molinillo identifies missing artifacts" do
81
+ let(:graph) do
82
+ graph = Solve::Graph.new
83
+ graph.artifact("A", "1.0.0")
84
+ graph
85
+ end
86
+
87
+ let(:demands) { [ ["Z"] ] }
88
+
89
+ it "raises an error detailing the missing artifacts" do
90
+ expect(error).to be_a_kind_of(Solve::Errors::NoSolutionError)
91
+ expected_error = <<-ERROR_MESSAGE
92
+ Unable to satisfy the following requirements:
93
+
94
+ - `Z (>= 0.0.0)` required by `Berksfile`
95
+ ERROR_MESSAGE
96
+ expect(error.to_s).to eq(expected_error)
97
+ end
98
+ end
99
+
100
+ context "and molinillo identifies constraints that exclude all known versions" do
101
+ let(:graph) do
102
+ graph = Solve::Graph.new
103
+ graph.artifact("A", "1.0.0")
104
+ graph
105
+ end
106
+
107
+ let(:demands) { [ ["A", "> 1.0.0"] ] }
108
+
109
+ it "raises an error detailing the missing artifacts" do
110
+ expect(error).to be_a_kind_of(Solve::Errors::NoSolutionError)
111
+ expected_error = <<-ERROR_MESSAGE
112
+ Unable to satisfy the following requirements:
113
+
114
+ - `A (> 1.0.0)` required by `Berksfile`
115
+ ERROR_MESSAGE
116
+ expect(error.to_s).to eq(expected_error)
117
+ end
118
+ end
119
+
120
+ context "and molinillo identifies dependency conflicts" do
121
+ let(:graph) do
122
+ graph = Solve::Graph.new
123
+ graph.artifact("A", "1.0.0").depends("B").depends("C")
124
+ graph.artifact("B", "1.0.0").depends("D", "= 1.0.0")
125
+ graph.artifact("C", "1.0.0").depends("D", "= 2.0.0")
126
+ graph.artifact("D", "1.0.0")
127
+ graph.artifact("D", "2.0.0")
128
+ graph
129
+ end
130
+
131
+ let(:demands) { [ [ "A" ] ] }
132
+
133
+ it "raises an error detailing the missing artifacts" do
134
+ expect(error).to be_a_kind_of(Solve::Errors::NoSolutionError)
135
+ expected_error = <<-ERROR_MESSAGE
136
+ Unable to satisfy the following requirements:
137
+
138
+ - `D (= 1.0.0)` required by `B-1.0.0`
139
+ - `D (= 2.0.0)` required by `C-1.0.0`
140
+ ERROR_MESSAGE
141
+ expect(error.to_s).to eq(expected_error)
142
+ end
143
+ end
144
+ end
145
+
146
+ describe "supporting Serializer interface" do
147
+ let(:serializer) { Solve::Solver::Serializer.new }
148
+
149
+ before do
150
+ graph.stub(:artifacts).and_return([])
151
+ end
152
+
153
+ it "implements the required interface" do
154
+ problem = Solve::Problem.from_solver(solver)
155
+ json_string = serializer.serialize(problem)
156
+ problem_data = JSON.parse(json_string)
157
+ expected_demands = [
158
+ {"name" => "mysql", "constraint" => ">= 0.0.0"},
159
+ {"name" => "nginx", "constraint" => ">= 0.0.0"}
160
+ ]
161
+
162
+ problem_data["demands"].should =~ expected_demands
163
+ end
164
+ end
165
+ end
166
+
@@ -1,25 +1,33 @@
1
1
  require 'spec_helper'
2
+ require 'solve/ruby_solver'
2
3
 
3
4
  describe Solve::Solver::Serializer do
4
- it "deserializes a serialized solver to an equivalent solver" do
5
- graph = Solve::Graph.new
6
5
 
7
- graph.artifact("A", "1.0.0").depends("B", "1.0.0")
8
- graph.artifact("B", "1.0.0").depends("C", "1.0.0")
9
- graph.artifact("C", "1.0.0")
6
+ let(:graph) do
7
+ Solve::Graph.new.tap do |g|
8
+ g.artifact("A", "1.0.0").depends("B", "1.0.0")
9
+ g.artifact("B", "1.0.0").depends("C", "1.0.0")
10
+ g.artifact("C", "1.0.0")
11
+ end
12
+ end
13
+
14
+ let(:demands) { [["A", "1.0.0"]] }
10
15
 
11
- demands = [["A", "1.0.0"]]
16
+ let(:serializer) { Solve::Solver::Serializer.new }
12
17
 
13
- solver = Solve::Solver.new(graph, demands)
14
- serializer = Solve::Solver::Serializer.new
15
- serialized = serializer.serialize(solver)
18
+ it "deserializes a serialized problem to an equivalent problem" do
19
+ problem = Solve::Problem.new(graph, demands)
20
+ serialized = serializer.serialize(problem)
16
21
  deserialized = serializer.deserialize(serialized)
17
22
 
18
- solver.graph.should eql(deserialized.graph)
19
- solver.demands.should eql(deserialized.demands)
23
+ problem.graph.should eql(deserialized.graph)
24
+ problem.demands.should eql(deserialized.demands)
25
+ end
20
26
 
21
- result = solver.resolve
22
- deserialized_result = deserialized.resolve
23
- result.should eql(deserialized_result)
27
+ it "creates a problem from a solver" do
28
+ solver = Solve::RubySolver.new(graph, demands)
29
+ problem = Solve::Problem.from_solver(solver)
30
+ expect(problem.demands).to eq([["A", "= 1.0.0"]])
31
+ expect(problem.graph).to eq(graph)
24
32
  end
25
33
  end
@@ -6,13 +6,13 @@ describe Solve do
6
6
 
7
7
  describe "#it" do
8
8
  it "returns nil if a solution does not exist" do
9
- pending
9
+ skip
10
10
  end
11
11
  end
12
12
 
13
13
  describe "#it!" do
14
14
  it "raises NoSolutionError if a solution does not exist" do
15
- pending
15
+ skip
16
16
  end
17
17
  end
18
18
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solve
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamie Winsor
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-07-18 00:00:00.000000000 Z
13
+ date: 2015-05-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: semverse
@@ -27,19 +27,75 @@ dependencies:
27
27
  - !ruby/object:Gem::Version
28
28
  version: '1.1'
29
29
  - !ruby/object:Gem::Dependency
30
- name: dep_selector
30
+ name: molinillo
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '1.0'
35
+ version: 0.2.3
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '1.0'
42
+ version: 0.2.3
43
+ - !ruby/object:Gem::Dependency
44
+ name: thor
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 0.16.0
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.16.0
57
+ - !ruby/object:Gem::Dependency
58
+ name: rake
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 0.9.2.2
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 0.9.2.2
71
+ - !ruby/object:Gem::Dependency
72
+ name: spork
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ - !ruby/object:Gem::Dependency
86
+ name: rspec
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - "~>"
90
+ - !ruby/object:Gem::Version
91
+ version: '3.0'
92
+ type: :development
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - "~>"
97
+ - !ruby/object:Gem::Version
98
+ version: '3.0'
43
99
  description: A Ruby version constraint solver
44
100
  email:
45
101
  - jamie@vialstudios.com
@@ -54,7 +110,9 @@ files:
54
110
  - Gemfile
55
111
  - Guardfile
56
112
  - LICENSE
113
+ - NoGecode.gemfile
57
114
  - README.md
115
+ - Rakefile
58
116
  - Thorfile
59
117
  - lib/solve.rb
60
118
  - lib/solve/artifact.rb
@@ -62,22 +120,25 @@ files:
62
120
  - lib/solve/demand.rb
63
121
  - lib/solve/dependency.rb
64
122
  - lib/solve/errors.rb
123
+ - lib/solve/gecode_solver.rb
65
124
  - lib/solve/graph.rb
66
- - lib/solve/solver.rb
125
+ - lib/solve/ruby_solver.rb
67
126
  - lib/solve/solver/serializer.rb
68
127
  - lib/solve/version.rb
69
128
  - solve.gemspec
70
129
  - spec/acceptance/benchmark.rb
71
130
  - spec/acceptance/large_graph_no_solution.rb
72
131
  - spec/acceptance/opscode_ci_graph.rb
132
+ - spec/acceptance/ruby_solver_solutions_spec.rb
73
133
  - spec/acceptance/solutions_spec.rb
74
134
  - spec/spec_helper.rb
75
135
  - spec/unit/solve/artifact_spec.rb
76
136
  - spec/unit/solve/demand_spec.rb
77
137
  - spec/unit/solve/dependency_spec.rb
138
+ - spec/unit/solve/gecode_solver_spec.rb
78
139
  - spec/unit/solve/graph_spec.rb
140
+ - spec/unit/solve/ruby_solver_spec.rb
79
141
  - spec/unit/solve/solver/serializer_spec.rb
80
- - spec/unit/solve/solver_spec.rb
81
142
  - spec/unit/solve_spec.rb
82
143
  homepage: https://github.com/berkshelf/solve
83
144
  licenses:
@@ -107,13 +168,15 @@ test_files:
107
168
  - spec/acceptance/benchmark.rb
108
169
  - spec/acceptance/large_graph_no_solution.rb
109
170
  - spec/acceptance/opscode_ci_graph.rb
171
+ - spec/acceptance/ruby_solver_solutions_spec.rb
110
172
  - spec/acceptance/solutions_spec.rb
111
173
  - spec/spec_helper.rb
112
174
  - spec/unit/solve/artifact_spec.rb
113
175
  - spec/unit/solve/demand_spec.rb
114
176
  - spec/unit/solve/dependency_spec.rb
177
+ - spec/unit/solve/gecode_solver_spec.rb
115
178
  - spec/unit/solve/graph_spec.rb
179
+ - spec/unit/solve/ruby_solver_spec.rb
116
180
  - spec/unit/solve/solver/serializer_spec.rb
117
- - spec/unit/solve/solver_spec.rb
118
181
  - spec/unit/solve_spec.rb
119
182
  has_rdoc: