solve 0.8.2 → 1.0.0.rc1
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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.travis.yml +4 -0
- data/README.md +8 -11
- data/lib/solve.rb +3 -8
- data/lib/solve/artifact.rb +44 -80
- data/lib/solve/constraint.rb +62 -46
- data/lib/solve/demand.rb +6 -21
- data/lib/solve/dependency.rb +10 -22
- data/lib/solve/errors.rb +43 -17
- data/lib/solve/gem_version.rb +1 -1
- data/lib/solve/graph.rb +43 -123
- data/lib/solve/solver.rb +134 -262
- data/lib/solve/solver/serializer.rb +1 -1
- data/solve.gemspec +3 -1
- data/spec/acceptance/benchmark.rb +45 -0
- data/spec/acceptance/large_graph_no_solution.rb +18730 -0
- data/spec/acceptance/opscode_ci_graph.rb +18600 -0
- data/spec/acceptance/solutions_spec.rb +117 -76
- data/spec/spec_helper.rb +3 -0
- data/spec/unit/solve/artifact_spec.rb +49 -64
- data/spec/unit/solve/demand_spec.rb +19 -56
- data/spec/unit/solve/dependency_spec.rb +7 -46
- data/spec/unit/solve/graph_spec.rb +72 -209
- data/spec/unit/solve/solver/serializer_spec.rb +3 -4
- data/spec/unit/solve/solver_spec.rb +103 -247
- metadata +43 -22
- data/.ruby-version +0 -1
- data/lib/solve/solver/constraint_row.rb +0 -25
- data/lib/solve/solver/constraint_table.rb +0 -31
- data/lib/solve/solver/variable_row.rb +0 -43
- data/lib/solve/solver/variable_table.rb +0 -55
- data/lib/solve/tracers.rb +0 -50
- data/lib/solve/tracers/human_readable.rb +0 -67
- data/lib/solve/tracers/silent.rb +0 -17
- data/lib/solve/version.rb +0 -140
- data/spec/unit/solve/constraint_spec.rb +0 -708
- data/spec/unit/solve/version_spec.rb +0 -355
| @@ -3,9 +3,9 @@ require 'spec_helper' | |
| 3 3 | 
             
            describe "Solutions" do
         | 
| 4 4 | 
             
              it "chooses the correct artifact for the demands" do
         | 
| 5 5 | 
             
                graph = Solve::Graph.new
         | 
| 6 | 
            -
                graph. | 
| 7 | 
            -
                graph. | 
| 8 | 
            -
                graph. | 
| 6 | 
            +
                graph.artifact("mysql", "2.0.0")
         | 
| 7 | 
            +
                graph.artifact("mysql", "1.2.0")
         | 
| 8 | 
            +
                graph.artifact("nginx", "1.0.0").depends("mysql", "= 1.2.0")
         | 
| 9 9 |  | 
| 10 10 | 
             
                result = Solve.it!(graph, [['nginx', '= 1.0.0'], ['mysql']])
         | 
| 11 11 |  | 
| @@ -14,9 +14,9 @@ describe "Solutions" do | |
| 14 14 |  | 
| 15 15 | 
             
              it "chooses the best artifact for the demands" do
         | 
| 16 16 | 
             
                graph = Solve::Graph.new
         | 
| 17 | 
            -
                graph. | 
| 18 | 
            -
                graph. | 
| 19 | 
            -
                graph. | 
| 17 | 
            +
                graph.artifact("mysql", "2.0.0")
         | 
| 18 | 
            +
                graph.artifact("mysql", "1.2.0")
         | 
| 19 | 
            +
                graph.artifact("nginx", "1.0.0").depends("mysql", ">= 1.2.0")
         | 
| 20 20 |  | 
| 21 21 | 
             
                result = Solve.it!(graph, [['nginx', '= 1.0.0'], ['mysql']])
         | 
| 22 22 |  | 
| @@ -25,7 +25,7 @@ describe "Solutions" do | |
| 25 25 |  | 
| 26 26 | 
             
              it "raises NoSolutionError when a solution cannot be found" do
         | 
| 27 27 | 
             
                graph = Solve::Graph.new
         | 
| 28 | 
            -
                graph. | 
| 28 | 
            +
                graph.artifact("mysql", "1.2.0")
         | 
| 29 29 |  | 
| 30 30 | 
             
                lambda {
         | 
| 31 31 | 
             
                  Solve.it!(graph, ['mysql', '>= 2.0.0'])
         | 
| @@ -35,27 +35,27 @@ describe "Solutions" do | |
| 35 35 | 
             
              it "find the correct solution when backtracking in variables introduced via demands" do
         | 
| 36 36 | 
             
                graph = Solve::Graph.new
         | 
| 37 37 |  | 
| 38 | 
            -
                graph. | 
| 39 | 
            -
                graph. | 
| 40 | 
            -
                graph. | 
| 41 | 
            -
                graph. | 
| 42 | 
            -
                graph. | 
| 38 | 
            +
                graph.artifact("D", "1.2.0")
         | 
| 39 | 
            +
                graph.artifact("D", "1.3.0")
         | 
| 40 | 
            +
                graph.artifact("D", "1.4.0")
         | 
| 41 | 
            +
                graph.artifact("D", "2.0.0")
         | 
| 42 | 
            +
                graph.artifact("D", "2.1.0")
         | 
| 43 43 |  | 
| 44 | 
            -
                graph. | 
| 45 | 
            -
                graph. | 
| 46 | 
            -
                graph. | 
| 44 | 
            +
                graph.artifact("C", "2.0.0").depends("D", "= 1.2.0")
         | 
| 45 | 
            +
                graph.artifact("C", "2.1.0").depends("D", ">= 2.1.0")
         | 
| 46 | 
            +
                graph.artifact("C", "2.2.0").depends("D", "> 2.0.0")
         | 
| 47 47 |  | 
| 48 | 
            -
                graph. | 
| 49 | 
            -
                graph. | 
| 50 | 
            -
                graph. | 
| 51 | 
            -
                graph. | 
| 48 | 
            +
                graph.artifact("B", "1.0.0").depends("D", "= 1.0.0")
         | 
| 49 | 
            +
                graph.artifact("B", "1.1.0").depends("D", "= 1.0.0")
         | 
| 50 | 
            +
                graph.artifact("B", "2.0.0").depends("D", ">= 1.3.0")
         | 
| 51 | 
            +
                graph.artifact("B", "2.1.0").depends("D", ">= 2.0.0")
         | 
| 52 52 |  | 
| 53 | 
            -
                graph. | 
| 54 | 
            -
                graph. | 
| 55 | 
            -
                graph. | 
| 56 | 
            -
                graph. | 
| 57 | 
            -
                graph. | 
| 58 | 
            -
                graph. | 
| 53 | 
            +
                graph.artifact("A", "1.0.0").depends("B", "> 2.0.0")
         | 
| 54 | 
            +
                graph.artifact("A", "1.0.0").depends("C", "= 2.1.0")
         | 
| 55 | 
            +
                graph.artifact("A", "1.0.1").depends("B", "> 1.0.0")
         | 
| 56 | 
            +
                graph.artifact("A", "1.0.1").depends("C", "= 2.1.0")
         | 
| 57 | 
            +
                graph.artifact("A", "1.0.2").depends("B", "> 1.0.0")
         | 
| 58 | 
            +
                graph.artifact("A", "1.0.2").depends("C", "= 2.0.0")
         | 
| 59 59 |  | 
| 60 60 | 
             
                result = Solve.it!(graph, [['A', '~> 1.0.0'], ['D', ">= 2.0.0"]])
         | 
| 61 61 |  | 
| @@ -69,9 +69,9 @@ describe "Solutions" do | |
| 69 69 | 
             
              it "finds the correct solution when there is a circular dependency" do
         | 
| 70 70 | 
             
                graph = Solve::Graph.new
         | 
| 71 71 |  | 
| 72 | 
            -
                graph. | 
| 73 | 
            -
                graph. | 
| 74 | 
            -
                graph. | 
| 72 | 
            +
                graph.artifact("A", "1.0.0").depends("B", "1.0.0")
         | 
| 73 | 
            +
                graph.artifact("B", "1.0.0").depends("C", "1.0.0")
         | 
| 74 | 
            +
                graph.artifact("C", "1.0.0").depends("A", "1.0.0")
         | 
| 75 75 |  | 
| 76 76 | 
             
                result = Solve.it!(graph, [["A", "1.0.0"]])
         | 
| 77 77 |  | 
| @@ -83,9 +83,9 @@ describe "Solutions" do | |
| 83 83 | 
             
              it "finds the correct solution when there is a p shaped depenency chain" do
         | 
| 84 84 | 
             
                graph = Solve::Graph.new
         | 
| 85 85 |  | 
| 86 | 
            -
                graph. | 
| 87 | 
            -
                graph. | 
| 88 | 
            -
                graph. | 
| 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 89 |  | 
| 90 90 | 
             
                result = Solve.it!(graph, [["A", "1.0.0"]])
         | 
| 91 91 |  | 
| @@ -97,14 +97,14 @@ describe "Solutions" do | |
| 97 97 | 
             
              it "finds the correct solution when there is a diamond shaped dependency" do
         | 
| 98 98 | 
             
                graph = Solve::Graph.new
         | 
| 99 99 |  | 
| 100 | 
            -
                graph. | 
| 100 | 
            +
                graph.artifact("A", "1.0.0")
         | 
| 101 101 | 
             
                  .depends("B", "1.0.0")
         | 
| 102 102 | 
             
                  .depends("C", "1.0.0")
         | 
| 103 | 
            -
                graph. | 
| 103 | 
            +
                graph.artifact("B", "1.0.0")
         | 
| 104 104 | 
             
                  .depends("D", "1.0.0")
         | 
| 105 | 
            -
                graph. | 
| 105 | 
            +
                graph.artifact("C", "1.0.0")
         | 
| 106 106 | 
             
                  .depends("D", "1.0.0")
         | 
| 107 | 
            -
                graph. | 
| 107 | 
            +
                graph.artifact("D", "1.0.0")
         | 
| 108 108 |  | 
| 109 109 | 
             
                result = Solve.it!(graph, [["A", "1.0.0"]])
         | 
| 110 110 |  | 
| @@ -114,11 +114,45 @@ describe "Solutions" do | |
| 114 114 | 
             
                                  "D" => "1.0.0")
         | 
| 115 115 | 
             
              end
         | 
| 116 116 |  | 
| 117 | 
            +
              it "solves when packages and constraints have prerelease elements" do
         | 
| 118 | 
            +
                graph = Solve::Graph.new
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                graph.artifact("A", "1.0.0")
         | 
| 121 | 
            +
                  .depends("B", ">= 1.0.0-alpha")
         | 
| 122 | 
            +
                graph.artifact("B", "1.0.0-alpha")
         | 
| 123 | 
            +
                  .depends("C", "1.0.0")
         | 
| 124 | 
            +
                graph.artifact("C", "1.0.0")
         | 
| 125 | 
            +
             | 
| 126 | 
            +
                result = Solve.it!(graph, [["A", "1.0.0"]])
         | 
| 127 | 
            +
             | 
| 128 | 
            +
                result.should eql("A" => "1.0.0",
         | 
| 129 | 
            +
                                  "B" => "1.0.0-alpha",
         | 
| 130 | 
            +
                                  "C" => "1.0.0")
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              end
         | 
| 133 | 
            +
             | 
| 134 | 
            +
              it "solves when packages and constraints have build elements" do
         | 
| 135 | 
            +
                graph = Solve::Graph.new
         | 
| 136 | 
            +
             | 
| 137 | 
            +
                graph.artifact("A", "1.0.0")
         | 
| 138 | 
            +
                  .depends("B", ">= 1.0.0+build")
         | 
| 139 | 
            +
                graph.artifact("B", "1.0.0+build")
         | 
| 140 | 
            +
                  .depends("C", "1.0.0")
         | 
| 141 | 
            +
                graph.artifact("C", "1.0.0")
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                result = Solve.it!(graph, [["A", "1.0.0"]])
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                result.should eql("A" => "1.0.0",
         | 
| 146 | 
            +
                                  "B" => "1.0.0+build",
         | 
| 147 | 
            +
                                  "C" => "1.0.0")
         | 
| 148 | 
            +
             | 
| 149 | 
            +
              end
         | 
| 150 | 
            +
             | 
| 117 151 | 
             
              it "fails with a self dependency" do
         | 
| 118 152 | 
             
                graph = Solve::Graph.new
         | 
| 119 153 |  | 
| 120 | 
            -
                graph. | 
| 121 | 
            -
                graph. | 
| 154 | 
            +
                graph.artifact("bottom", "1.0.0")
         | 
| 155 | 
            +
                graph.artifact("middle", "1.0.0").depends("top", "= 1.0.0").depends("middle")
         | 
| 122 156 |  | 
| 123 157 | 
             
                demands = [["bottom", "1.0.0"],["middle", "1.0.0"]]
         | 
| 124 158 |  | 
| @@ -137,28 +171,28 @@ describe "Solutions" do | |
| 137 171 |  | 
| 138 172 | 
             
                graph = Solve::Graph.new
         | 
| 139 173 |  | 
| 140 | 
            -
                graph. | 
| 141 | 
            -
                graph. | 
| 142 | 
            -
                graph. | 
| 174 | 
            +
                graph.artifact("A", "1.0.0").depends("B", "~> 1.0.0")
         | 
| 175 | 
            +
                graph.artifact("A", "1.0.1").depends("B", "~> 1.0.0")
         | 
| 176 | 
            +
                graph.artifact("A", "1.0.2").depends("B", "~> 1.0.0")
         | 
| 143 177 |  | 
| 144 | 
            -
                graph. | 
| 145 | 
            -
                graph. | 
| 146 | 
            -
                graph. | 
| 178 | 
            +
                graph.artifact("B", "1.0.0").depends("C", "~> 1.0.0")
         | 
| 179 | 
            +
                graph.artifact("B", "1.0.1").depends("C", "~> 1.0.0")
         | 
| 180 | 
            +
                graph.artifact("B", "1.0.2").depends("C", "~> 1.0.0")
         | 
| 147 181 |  | 
| 148 | 
            -
                graph. | 
| 149 | 
            -
                graph. | 
| 150 | 
            -
                graph. | 
| 182 | 
            +
                graph.artifact("C", "1.0.0").depends("D", "1.0.0")
         | 
| 183 | 
            +
                graph.artifact("C", "1.0.1").depends("D", "1.0.0")
         | 
| 184 | 
            +
                graph.artifact("C", "1.0.2").depends("D", "1.0.0")
         | 
| 151 185 |  | 
| 152 186 | 
             
                # ensure we can't find a solution in the above
         | 
| 153 | 
            -
                graph. | 
| 187 | 
            +
                graph.artifact("D", "1.0.0").depends("A", "< 0.0.0")
         | 
| 154 188 |  | 
| 155 189 | 
             
                # Add a solution to the graph that should be reached only after
         | 
| 156 190 | 
             
                #   all of the others have been tried
         | 
| 157 191 | 
             
                #   it must be circular to ensure that no other branch can find it
         | 
| 158 | 
            -
                graph. | 
| 159 | 
            -
                graph. | 
| 160 | 
            -
                graph. | 
| 161 | 
            -
                graph. | 
| 192 | 
            +
                graph.artifact("A", "0.0.0").depends("B", "0.0.0")
         | 
| 193 | 
            +
                graph.artifact("B", "0.0.0").depends("C", "0.0.0")
         | 
| 194 | 
            +
                graph.artifact("C", "0.0.0").depends("D", "0.0.0")
         | 
| 195 | 
            +
                graph.artifact("D", "0.0.0").depends("A", "0.0.0")
         | 
| 162 196 |  | 
| 163 197 | 
             
                demands = [["A"]]
         | 
| 164 198 |  | 
| @@ -174,33 +208,40 @@ describe "Solutions" do | |
| 174 208 | 
             
              it "correctly resolves when a resolution exists but it is not the latest" do
         | 
| 175 209 | 
             
                graph = Solve::Graph.new
         | 
| 176 210 |  | 
| 177 | 
            -
                graph. | 
| 211 | 
            +
                graph.artifact("get-the-old-one", "1.0.0")
         | 
| 178 212 | 
             
                  .depends("locked-mid-1", ">= 0.0.0")
         | 
| 179 213 | 
             
                  .depends("locked-mid-2", ">= 0.0.0")
         | 
| 180 | 
            -
                graph. | 
| 214 | 
            +
                graph.artifact("get-the-old-one", "0.5.0")
         | 
| 181 215 |  | 
| 182 | 
            -
                graph. | 
| 183 | 
            -
                graph. | 
| 184 | 
            -
                graph. | 
| 216 | 
            +
                graph.artifact("locked-mid-1", "2.0.0").depends("old-bottom", "= 2.0.0")
         | 
| 217 | 
            +
                graph.artifact("locked-mid-1", "1.3.0").depends("old-bottom", "= 0.5.0")
         | 
| 218 | 
            +
                graph.artifact("locked-mid-1", "1.0.0")
         | 
| 185 219 |  | 
| 186 | 
            -
                graph. | 
| 187 | 
            -
                graph. | 
| 188 | 
            -
                graph. | 
| 220 | 
            +
                graph.artifact("locked-mid-2", "2.0.0").depends("old-bottom", "= 2.1.0")
         | 
| 221 | 
            +
                graph.artifact("locked-mid-2", "1.4.0").depends("old-bottom", "= 0.5.0")
         | 
| 222 | 
            +
                graph.artifact("locked-mid-2", "1.0.0")
         | 
| 189 223 |  | 
| 190 | 
            -
                graph. | 
| 191 | 
            -
                graph. | 
| 192 | 
            -
                graph. | 
| 193 | 
            -
                graph. | 
| 224 | 
            +
                graph.artifact("old-bottom", "2.1.0")
         | 
| 225 | 
            +
                graph.artifact("old-bottom", "2.0.0")
         | 
| 226 | 
            +
                graph.artifact("old-bottom", "1.0.0")
         | 
| 227 | 
            +
                graph.artifact("old-bottom", "0.5.0")
         | 
| 194 228 |  | 
| 195 229 | 
             
                demands = [["get-the-old-one"]]
         | 
| 196 230 |  | 
| 197 231 | 
             
                result = Solve.it!(graph, demands)
         | 
| 198 232 |  | 
| 233 | 
            +
                # ruby solver result:
         | 
| 234 | 
            +
                #
         | 
| 235 | 
            +
                # "get-the-old-one" => "1.0.0",
         | 
| 236 | 
            +
                # "locked-mid-1" => "2.0.0",
         | 
| 237 | 
            +
                # "locked-mid-2" => "1.0.0",
         | 
| 238 | 
            +
                # "old-bottom" => "2.0.0"
         | 
| 239 | 
            +
             | 
| 199 240 | 
             
                result.should eql({
         | 
| 200 241 | 
             
                  "get-the-old-one" => "1.0.0",
         | 
| 201 | 
            -
                  "locked-mid-1" => " | 
| 202 | 
            -
                  "locked-mid-2" => " | 
| 203 | 
            -
                  "old-bottom" => "2. | 
| 242 | 
            +
                  "locked-mid-1" => "1.0.0",
         | 
| 243 | 
            +
                  "locked-mid-2" => "2.0.0",
         | 
| 244 | 
            +
                  "old-bottom" => "2.1.0"
         | 
| 204 245 | 
             
                })
         | 
| 205 246 | 
             
              end
         | 
| 206 247 |  | 
| @@ -209,9 +250,9 @@ describe "Solutions" do | |
| 209 250 | 
             
                  it "returns a sorted list of dependencies" do
         | 
| 210 251 | 
             
                    graph = Solve::Graph.new
         | 
| 211 252 |  | 
| 212 | 
            -
                    graph. | 
| 213 | 
            -
                    graph. | 
| 214 | 
            -
                    graph. | 
| 253 | 
            +
                    graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
         | 
| 254 | 
            +
                    graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
         | 
| 255 | 
            +
                    graph.artifact("C", "1.0.0")
         | 
| 215 256 |  | 
| 216 257 | 
             
                    demands = [["A"]]
         | 
| 217 258 |  | 
| @@ -231,11 +272,11 @@ describe "Solutions" do | |
| 231 272 | 
             
                  it "returns a sorted list of dependencies" do
         | 
| 232 273 | 
             
                    graph = Solve::Graph.new
         | 
| 233 274 |  | 
| 234 | 
            -
                    graph. | 
| 235 | 
            -
                    graph. | 
| 236 | 
            -
                    graph. | 
| 275 | 
            +
                    graph.artifact("B", "1.0.0").depends("A", "= 1.0.0")
         | 
| 276 | 
            +
                    graph.artifact("A", "1.0.0").depends("C", "= 1.0.0")
         | 
| 277 | 
            +
                    graph.artifact("C", "1.0.0")
         | 
| 237 278 |  | 
| 238 | 
            -
                    demands = [["A"],["B"]] | 
| 279 | 
            +
                    demands = [["A"],["B"]]
         | 
| 239 280 |  | 
| 240 281 | 
             
                    result = Solve.it!(graph, demands, { :sorted => true  } )
         | 
| 241 282 |  | 
| @@ -251,9 +292,9 @@ describe "Solutions" do | |
| 251 292 | 
             
                  it "raises a Solve::Errors::UnsortableSolutionError which contains the unsorted solution" do
         | 
| 252 293 | 
             
                    graph = Solve::Graph.new
         | 
| 253 294 |  | 
| 254 | 
            -
                    graph. | 
| 255 | 
            -
                    graph. | 
| 256 | 
            -
                    graph. | 
| 295 | 
            +
                    graph.artifact("A", "1.0.0").depends("B", "= 1.0.0")
         | 
| 296 | 
            +
                    graph.artifact("B", "1.0.0").depends("C", "= 1.0.0")
         | 
| 297 | 
            +
                    graph.artifact("C", "1.0.0").depends("A", "= 1.0.0")
         | 
| 257 298 |  | 
| 258 299 | 
             
                    demands = [["A"]]
         | 
| 259 300 |  | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
| @@ -19,7 +19,7 @@ describe Solve::Artifact do | |
| 19 19 | 
             
                  let(:two) { Solve::Artifact.new(graph, "riot", "1.0.0") }
         | 
| 20 20 |  | 
| 21 21 | 
             
                  it "is equal" do
         | 
| 22 | 
            -
                    one. | 
| 22 | 
            +
                    expect(one).to eq(two)
         | 
| 23 23 | 
             
                  end
         | 
| 24 24 | 
             
                end
         | 
| 25 25 |  | 
| @@ -28,7 +28,7 @@ describe Solve::Artifact do | |
| 28 28 | 
             
                  let(:two) { Solve::Artifact.new(graph, "riot", "2.0.0") }
         | 
| 29 29 |  | 
| 30 30 | 
             
                  it "is not equal" do
         | 
| 31 | 
            -
                    one. | 
| 31 | 
            +
                    expect(one).to_not eq(two)
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 | 
             
                end
         | 
| 34 34 |  | 
| @@ -37,7 +37,7 @@ describe Solve::Artifact do | |
| 37 37 | 
             
                  let(:two) { Solve::Artifact.new(graph, "league", "1.0.0") }
         | 
| 38 38 |  | 
| 39 39 | 
             
                  it "is not equal" do
         | 
| 40 | 
            -
                    one. | 
| 40 | 
            +
                    expect(one).to_not eq(two)
         | 
| 41 41 | 
             
                  end
         | 
| 42 42 | 
             
                end
         | 
| 43 43 | 
             
              end
         | 
| @@ -58,40 +58,69 @@ describe Solve::Artifact do | |
| 58 58 | 
             
                it "orders artifacts by their version number" do
         | 
| 59 59 | 
             
                  sorted = artifacts.sort
         | 
| 60 60 |  | 
| 61 | 
            -
                  sorted[0]. | 
| 62 | 
            -
                  sorted[1]. | 
| 63 | 
            -
                  sorted[2]. | 
| 61 | 
            +
                  expect(sorted[0]).to eq(one)
         | 
| 62 | 
            +
                  expect(sorted[1]).to eq(two)
         | 
| 63 | 
            +
                  expect(sorted[2]).to eq(three)
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
              end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
              describe "#dependency?" do
         | 
| 68 | 
            +
                before { subject.depends("nginx", "1.0.0") }
         | 
| 69 | 
            +
             | 
| 70 | 
            +
                it "returns false when the dependency does not exist" do
         | 
| 71 | 
            +
                  expect(subject).to have_dependency("nginx", "1.0.0")
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                it "returns true when the dependendency exists" do
         | 
| 75 | 
            +
                  expect(subject).to_not have_dependency("apache2", "2.0.0")
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              describe "#dependency" do
         | 
| 80 | 
            +
                before { subject.depends("nginx", "~> 1.2.3") }
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                it "returns an instance of Solve::Dependency matching the given name and constraint" do
         | 
| 83 | 
            +
                  dependency = subject.dependency("nginx", "~> 1.2.3")
         | 
| 84 | 
            +
             | 
| 85 | 
            +
                  expect(dependency).to be_a(Solve::Dependency)
         | 
| 86 | 
            +
                  expect(dependency.name).to eq("nginx")
         | 
| 87 | 
            +
                  expect(dependency.constraint.to_s).to eq("~> 1.2.3")
         | 
| 64 88 | 
             
                end
         | 
| 65 89 | 
             
              end
         | 
| 66 90 |  | 
| 67 91 | 
             
              describe "#dependencies" do
         | 
| 68 | 
            -
                 | 
| 69 | 
            -
                   | 
| 70 | 
            -
             | 
| 71 | 
            -
                  end
         | 
| 92 | 
            +
                it "returns an array" do
         | 
| 93 | 
            +
                  expect(subject.dependencies).to be_a(Array)
         | 
| 94 | 
            +
                end
         | 
| 72 95 |  | 
| 73 | 
            -
             | 
| 74 | 
            -
             | 
| 75 | 
            -
             | 
| 96 | 
            +
                it "returns an empty array if no dependencies have been accessed" do
         | 
| 97 | 
            +
                  expect(subject.dependencies).to be_empty
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                it "returns all dependencies" do
         | 
| 101 | 
            +
                  subject.depends("nginx", "1.0.0")
         | 
| 102 | 
            +
                  subject.depends("nginx", "~> 2.0.0")
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                  expect(subject.dependencies.size).to eq(2)
         | 
| 76 105 | 
             
                end
         | 
| 77 106 | 
             
              end
         | 
| 78 107 |  | 
| 79 108 | 
             
              describe "#depends" do
         | 
| 80 109 | 
             
                context "given a name and constraint argument" do
         | 
| 81 110 | 
             
                  let(:name) { "nginx" }
         | 
| 82 | 
            -
                  let(:constraint) { "~> 0. | 
| 111 | 
            +
                  let(:constraint) { "~> 1.0.0" }
         | 
| 83 112 |  | 
| 84 113 | 
             
                  context "given the dependency of the given name and constraint does not exist" do
         | 
| 85 114 | 
             
                    it "returns a Solve::Artifact" do
         | 
| 86 | 
            -
                      subject.depends(name, constraint). | 
| 115 | 
            +
                      expect(subject.depends(name, constraint)).to be_a(Solve::Artifact)
         | 
| 87 116 | 
             
                    end
         | 
| 88 117 |  | 
| 89 118 | 
             
                    it "adds a dependency with the given name and constraint to the list of dependencies" do
         | 
| 90 119 | 
             
                      subject.depends(name, constraint)
         | 
| 91 120 |  | 
| 92 | 
            -
                      subject.dependencies. | 
| 93 | 
            -
                      subject.dependencies.first.name. | 
| 94 | 
            -
                      subject.dependencies.first.constraint.to_s. | 
| 121 | 
            +
                      expect(subject.dependencies.size).to eq(1)
         | 
| 122 | 
            +
                      expect(subject.dependencies.first.name).to eq(name)
         | 
| 123 | 
            +
                      expect(subject.dependencies.first.constraint.to_s).to eq(constraint)
         | 
| 95 124 | 
             
                    end
         | 
| 96 125 | 
             
                  end
         | 
| 97 126 | 
             
                end
         | 
| @@ -100,52 +129,8 @@ describe Solve::Artifact do | |
| 100 129 | 
             
                  it "adds a dependency with a all constraint (>= 0.0.0)" do
         | 
| 101 130 | 
             
                    subject.depends("nginx")
         | 
| 102 131 |  | 
| 103 | 
            -
                    subject.dependencies. | 
| 104 | 
            -
                    subject.dependencies.first.constraint.to_s. | 
| 105 | 
            -
                  end
         | 
| 106 | 
            -
                end
         | 
| 107 | 
            -
              end
         | 
| 108 | 
            -
             | 
| 109 | 
            -
              describe "::get_dependency" do
         | 
| 110 | 
            -
                before(:each) { subject.depends("nginx", "~> 1.2.3") }
         | 
| 111 | 
            -
             | 
| 112 | 
            -
                it "returns an instance of Solve::Dependency matching the given name and constraint" do
         | 
| 113 | 
            -
                  dependency = subject.get_dependency("nginx", "~> 1.2.3")
         | 
| 114 | 
            -
             | 
| 115 | 
            -
                  dependency.should be_a(Solve::Dependency)
         | 
| 116 | 
            -
                  dependency.name.should eql("nginx")
         | 
| 117 | 
            -
                  dependency.constraint.to_s.should eql("~> 1.2.3")
         | 
| 118 | 
            -
                end
         | 
| 119 | 
            -
              end
         | 
| 120 | 
            -
             | 
| 121 | 
            -
              describe "#delete" do
         | 
| 122 | 
            -
                context "given the artifact is a member of a graph" do
         | 
| 123 | 
            -
                  subject { Solve::Artifact.new(graph, name, version) }
         | 
| 124 | 
            -
             | 
| 125 | 
            -
                  before(:each) do
         | 
| 126 | 
            -
                    graph.should_receive(:remove_artifact).with(subject).and_return(subject)
         | 
| 127 | 
            -
                  end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                  it "notifies the graph that the artifact should be removed" do
         | 
| 130 | 
            -
                    subject.delete
         | 
| 131 | 
            -
                  end
         | 
| 132 | 
            -
             | 
| 133 | 
            -
                  it "sets the graph attribute to nil" do
         | 
| 134 | 
            -
                    subject.delete
         | 
| 135 | 
            -
             | 
| 136 | 
            -
                    subject.graph.should be_nil
         | 
| 137 | 
            -
                  end
         | 
| 138 | 
            -
             | 
| 139 | 
            -
                  it "returns the instance of artifact deleted from the graph" do
         | 
| 140 | 
            -
                    subject.delete.should eql(subject)
         | 
| 141 | 
            -
                  end
         | 
| 142 | 
            -
                end
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                context "given the artifact is not the member of a graph" do
         | 
| 145 | 
            -
                  subject { Solve::Artifact.new(nil, name, version) }
         | 
| 146 | 
            -
             | 
| 147 | 
            -
                  it "returns nil" do
         | 
| 148 | 
            -
                    subject.delete.should be_nil
         | 
| 132 | 
            +
                    expect(subject.dependencies.size).to eq(1)
         | 
| 133 | 
            +
                    expect(subject.dependencies.first.constraint.to_s).to eq(">= 0.0.0")
         | 
| 149 134 | 
             
                  end
         | 
| 150 135 | 
             
                end
         | 
| 151 136 | 
             
              end
         |