|
59 | 59 | end |
60 | 60 |
|
61 | 61 | let(:updated_dependencies) do |
62 | | - [ |
63 | | - Dependabot::Dependency.new( |
64 | | - name: "dummy-pkg-b", |
65 | | - package_manager: "bundler", |
66 | | - version: "1.2.0", |
67 | | - previous_version: "1.1.0", |
68 | | - requirements: [ |
69 | | - { |
70 | | - file: "Gemfile", |
71 | | - requirement: "~> 1.2.0", |
72 | | - groups: [], |
73 | | - source: nil |
74 | | - } |
75 | | - ], |
76 | | - previous_requirements: [ |
77 | | - { |
78 | | - file: "Gemfile", |
79 | | - requirement: "~> 1.1.0", |
80 | | - groups: [], |
81 | | - source: nil |
82 | | - } |
83 | | - ] |
84 | | - ) |
85 | | - ] |
| 62 | + [build_dependency(name: "dummy-pkg-b", version: "1.2.0", previous_version: "1.1.0")] |
86 | 63 | end |
87 | 64 |
|
88 | 65 | describe "::create_from" do |
|
91 | 68 | job: job, |
92 | 69 | dependency_files: dependency_files, |
93 | 70 | updated_dependencies: updated_dependencies, |
94 | | - change_source: change_source |
| 71 | + change_source: change_source, |
| 72 | + notices: notices |
95 | 73 | ) |
96 | 74 | end |
97 | 75 |
|
98 | | - context "when the source is a lead dependency" do |
99 | | - let(:change_source) do |
100 | | - Dependabot::Dependency.new( |
101 | | - name: "dummy-pkg-b", |
102 | | - package_manager: "bundler", |
103 | | - version: "1.1.0", |
104 | | - requirements: [ |
105 | | - { |
106 | | - file: "Gemfile", |
107 | | - requirement: "~> 1.1.0", |
108 | | - groups: [], |
109 | | - source: nil |
110 | | - } |
111 | | - ] |
112 | | - ) |
| 76 | + let(:notices) { [] } |
| 77 | + let(:lead_dependency_change_source) { build_dependency(name: "dummy-pkg-b", version: "1.1.0") } |
| 78 | + let(:single_dependency_info) { "dummy-pkg-b (1.1.0 → 1.2.0)" } |
| 79 | + let(:file_updater_class) { class_double(Dependabot::Bundler::FileUpdater) } |
| 80 | + |
| 81 | + def stub_file_updater(updated_dependency_files:, notices: []) |
| 82 | + file_updater = instance_double( |
| 83 | + Dependabot::Bundler::FileUpdater, |
| 84 | + updated_dependency_files: updated_dependency_files, |
| 85 | + notices: notices |
| 86 | + ) |
| 87 | + |
| 88 | + allow(Dependabot::FileUpdaters).to receive(:for_package_manager) |
| 89 | + .with("bundler") |
| 90 | + .and_return(file_updater_class) |
| 91 | + allow(file_updater_class).to receive(:new).and_return(file_updater) |
| 92 | + end |
| 93 | + |
| 94 | + def build_dependency(name:, version:, previous_version: nil) |
| 95 | + requirement = { |
| 96 | + file: "Gemfile", |
| 97 | + requirement: "~> #{version}", |
| 98 | + groups: [], |
| 99 | + source: nil |
| 100 | + } |
| 101 | + |
| 102 | + dependency_args = { |
| 103 | + name: name, |
| 104 | + package_manager: "bundler", |
| 105 | + version: version, |
| 106 | + requirements: [requirement] |
| 107 | + } |
| 108 | + |
| 109 | + if previous_version |
| 110 | + previous_requirement = { |
| 111 | + file: "Gemfile", |
| 112 | + requirement: "~> #{previous_version}", |
| 113 | + groups: [], |
| 114 | + source: nil |
| 115 | + } |
| 116 | + |
| 117 | + dependency_args[:previous_version] = previous_version |
| 118 | + dependency_args[:previous_requirements] = [previous_requirement] |
113 | 119 | end |
114 | 120 |
|
| 121 | + Dependabot::Dependency.new(**dependency_args) |
| 122 | + end |
| 123 | + |
| 124 | + def dependency_group_source |
| 125 | + Dependabot::DependencyGroup.new(name: "dummy-pkg-*", rules: { patterns: ["dummy-pkg-*"] }) |
| 126 | + end |
| 127 | + |
| 128 | + context "when the source is a lead dependency" do |
| 129 | + let(:change_source) { lead_dependency_change_source } |
| 130 | + |
115 | 131 | it "creates a new DependencyChange with the updated files" do |
116 | 132 | dependency_change = create_change |
117 | 133 |
|
|
128 | 144 | end |
129 | 145 |
|
130 | 146 | it "does not include support files in the updated files" do |
131 | | - allow_any_instance_of(Dependabot::Bundler::FileUpdater) |
132 | | - .to receive(:updated_dependency_files) |
133 | | - .and_return(dependency_files) |
| 147 | + stub_file_updater(updated_dependency_files: dependency_files) |
134 | 148 |
|
135 | 149 | dependency_change = described_class.create_from( |
136 | 150 | job: job, |
|
145 | 159 | end |
146 | 160 |
|
147 | 161 | context "when the source is a dependency group" do |
148 | | - let(:change_source) do |
149 | | - Dependabot::DependencyGroup.new(name: "dummy-pkg-*", rules: { patterns: ["dummy-pkg-*"] }) |
150 | | - end |
| 162 | + let(:change_source) { dependency_group_source } |
151 | 163 |
|
152 | 164 | it "creates a new DependencyChange flagged as a grouped update" do |
153 | 165 | dependency_change = create_change |
|
158 | 170 | end |
159 | 171 |
|
160 | 172 | context "when there are no file changes" do |
161 | | - let(:change_source) do |
162 | | - Dependabot::Dependency.new( |
163 | | - name: "dummy-pkg-b", |
164 | | - package_manager: "bundler", |
165 | | - version: "1.1.0", |
166 | | - requirements: [ |
167 | | - { |
168 | | - file: "Gemfile", |
169 | | - requirement: "~> 1.1.0", |
170 | | - groups: [], |
171 | | - source: nil |
172 | | - } |
173 | | - ] |
174 | | - ) |
| 173 | + let(:change_source) { lead_dependency_change_source } |
| 174 | + |
| 175 | + before do |
| 176 | + stub_file_updater(updated_dependency_files: []) |
| 177 | + end |
| 178 | + |
| 179 | + it "raises an exception with diagnostic dependency details" do |
| 180 | + expect { create_change } |
| 181 | + .to raise_error( |
| 182 | + Dependabot::DependabotError, |
| 183 | + "FileUpdater failed to update any files for: dummy-pkg-b (1.1.0 → 1.2.0)" |
| 184 | + ) |
| 185 | + end |
| 186 | + end |
| 187 | + |
| 188 | + context "when multiple dependencies have no file changes" do |
| 189 | + let(:updated_dependencies) do |
| 190 | + [ |
| 191 | + build_dependency(name: "dummy-pkg-b", version: "1.2.0", previous_version: "1.1.0"), |
| 192 | + build_dependency(name: "dummy-pkg-a", version: "2.0.0", previous_version: "1.9.0") |
| 193 | + ] |
| 194 | + end |
| 195 | + |
| 196 | + let(:change_source) { dependency_group_source } |
| 197 | + |
| 198 | + before do |
| 199 | + stub_file_updater(updated_dependency_files: []) |
| 200 | + end |
| 201 | + |
| 202 | + it "raises an exception listing dependency names" do |
| 203 | + expect { create_change } |
| 204 | + .to raise_error( |
| 205 | + Dependabot::DependabotError, |
| 206 | + "FileUpdater failed to update any files for: dummy-pkg-a, dummy-pkg-b" |
| 207 | + ) |
| 208 | + end |
| 209 | + end |
| 210 | + |
| 211 | + context "when duplicate dependency names have no file changes" do |
| 212 | + let(:updated_dependencies) do |
| 213 | + [ |
| 214 | + build_dependency(name: "dummy-pkg-b", version: "1.2.0", previous_version: "1.1.0"), |
| 215 | + build_dependency(name: "dummy-pkg-b", version: "1.3.0", previous_version: "1.2.0") |
| 216 | + ] |
| 217 | + end |
| 218 | + |
| 219 | + let(:change_source) { dependency_group_source } |
| 220 | + |
| 221 | + before do |
| 222 | + stub_file_updater(updated_dependency_files: []) |
| 223 | + end |
| 224 | + |
| 225 | + it "raises an exception with unique dependency names" do |
| 226 | + expect { create_change } |
| 227 | + .to raise_error( |
| 228 | + Dependabot::DependabotError, |
| 229 | + "FileUpdater failed to update any files for: dummy-pkg-b" |
| 230 | + ) |
| 231 | + end |
| 232 | + end |
| 233 | + |
| 234 | + context "when only support files are returned" do |
| 235 | + let(:change_source) { lead_dependency_change_source } |
| 236 | + let(:support_files) { dependency_files.select(&:support_file?) } |
| 237 | + let(:updated_support_files) { [support_files.last, support_files.first, support_files.last] } |
| 238 | + let(:updater_notices) { [instance_double(Dependabot::Notice)] } |
| 239 | + |
| 240 | + before do |
| 241 | + stub_file_updater(updated_dependency_files: updated_support_files, notices: updater_notices) |
| 242 | + end |
| 243 | + |
| 244 | + it "raises a generic no-files error" do |
| 245 | + expect { create_change } |
| 246 | + .to raise_error( |
| 247 | + Dependabot::DependabotError, |
| 248 | + "FileUpdater failed to update any files for: dummy-pkg-b (1.1.0 → 1.2.0)" |
| 249 | + ) |
| 250 | + end |
| 251 | + |
| 252 | + it "collects notices before raising" do |
| 253 | + expect { create_change } |
| 254 | + .to raise_error( |
| 255 | + Dependabot::DependabotError, |
| 256 | + "FileUpdater failed to update any files for: dummy-pkg-b (1.1.0 → 1.2.0)" |
| 257 | + ) |
| 258 | + |
| 259 | + expect(notices).to eq(updater_notices) |
| 260 | + end |
| 261 | + end |
| 262 | + |
| 263 | + context "when grouped updates return only support files" do |
| 264 | + let(:updated_dependencies) do |
| 265 | + [ |
| 266 | + build_dependency(name: "dummy-pkg-b", version: "1.2.0", previous_version: "1.1.0"), |
| 267 | + build_dependency(name: "dummy-pkg-a", version: "2.0.0", previous_version: "1.9.0"), |
| 268 | + build_dependency(name: "dummy-pkg-b", version: "1.3.0", previous_version: "1.2.0") |
| 269 | + ] |
175 | 270 | end |
| 271 | + let(:change_source) { dependency_group_source } |
| 272 | + let(:support_files) { dependency_files.select(&:support_file?) } |
176 | 273 |
|
177 | 274 | before do |
178 | | - allow_any_instance_of(Dependabot::Bundler::FileUpdater).to receive(:updated_dependency_files).and_return([]) |
| 275 | + stub_file_updater(updated_dependency_files: support_files) |
179 | 276 | end |
180 | 277 |
|
181 | | - it "raises an exception" do |
182 | | - expect { create_change }.to raise_error(Dependabot::DependabotError) |
| 278 | + it "raises a no-files error listing sorted and unique dependency names" do |
| 279 | + expect { create_change } |
| 280 | + .to raise_error( |
| 281 | + Dependabot::DependabotError, |
| 282 | + "FileUpdater failed to update any files for: dummy-pkg-a, dummy-pkg-b" |
| 283 | + ) |
183 | 284 | end |
184 | 285 | end |
185 | 286 | end |
|
0 commit comments