solve 1.2.1 → 2.0.0

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,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: