|  | 
| 66 | 66 |   describe "#check_node_version" do | 
| 67 | 67 |     context "when Node.js version is too old" do | 
| 68 | 68 |       before do | 
| 69 |  | -        allow(checker).to receive(:`).with("node --version 2>/dev/null").and_return("v16.14.0\n") | 
|  | 69 | +        allow(Open3).to receive(:capture3).with("node", "--version") | 
|  | 70 | +                    .and_return(["v16.14.0\n", "", instance_double(Process::Status, success?: true)]) | 
| 70 | 71 |       end | 
| 71 | 72 | 
 | 
| 72 | 73 |       it "adds a warning message" do | 
|  | 
| 78 | 79 | 
 | 
| 79 | 80 |     context "when Node.js version is compatible" do | 
| 80 | 81 |       before do | 
| 81 |  | -        allow(checker).to receive(:`).with("node --version 2>/dev/null").and_return("v18.17.0\n") | 
|  | 82 | +        allow(Open3).to receive(:capture3).with("node", "--version") | 
|  | 83 | +                    .and_return(["v18.17.0\n", "", instance_double(Process::Status, success?: true)]) | 
| 82 | 84 |       end | 
| 83 | 85 | 
 | 
| 84 | 86 |       it "adds a success message" do | 
|  | 
| 91 | 93 | 
 | 
| 92 | 94 |     context "when Node.js version cannot be determined" do | 
| 93 | 95 |       before do | 
| 94 |  | -        allow(checker).to receive(:`).with("node --version 2>/dev/null").and_return("") | 
|  | 96 | +        allow(Open3).to receive(:capture3).with("node", "--version") | 
|  | 97 | +                    .and_return(["", "", instance_double(Process::Status, success?: false)]) | 
| 95 | 98 |       end | 
| 96 | 99 | 
 | 
| 97 | 100 |       it "does not add any messages" do | 
|  | 
| 122 | 125 |         allow(checker).to receive(:cli_exists?).with("yarn").and_return(true) | 
| 123 | 126 |         allow(checker).to receive(:cli_exists?).with("pnpm").and_return(false) | 
| 124 | 127 |         allow(checker).to receive(:cli_exists?).with("bun").and_return(false) | 
|  | 128 | +        # Mock file existence checks for lock files so detect_used_package_manager returns nil | 
|  | 129 | +        allow(File).to receive(:exist?).with("yarn.lock").and_return(false) | 
|  | 130 | +        allow(File).to receive(:exist?).with("pnpm-lock.yaml").and_return(false) | 
|  | 131 | +        allow(File).to receive(:exist?).with("bun.lockb").and_return(false) | 
|  | 132 | +        allow(File).to receive(:exist?).with("package-lock.json").and_return(false) | 
| 125 | 133 |       end | 
| 126 | 134 | 
 | 
| 127 | 135 |       it "adds a success message" do | 
| 128 | 136 |         result = checker.check_package_manager | 
| 129 | 137 |         expect(result).to be true | 
| 130 |  | -        expect(checker.messages.any? { |msg| msg[:type] == :success && msg[:content].include?("npm, yarn") }).to be true | 
|  | 138 | +        expect(checker.messages.any? do |msg| | 
|  | 139 | +                 msg[:type] == :success && msg[:content].include?("Package managers available: npm, yarn") | 
|  | 140 | +               end).to be true | 
| 131 | 141 |       end | 
| 132 | 142 |     end | 
| 133 | 143 |   end | 
|  | 
| 150 | 160 |       before do | 
| 151 | 161 |         allow(checker).to receive(:shakapacker_configured?).and_return(true) | 
| 152 | 162 |         allow(checker).to receive(:check_shakapacker_in_gemfile) | 
|  | 163 | +        allow(File).to receive(:exist?).with("Gemfile.lock").and_return(true) | 
|  | 164 | +        lockfile_content = %(GEM\n  remote: https://rubygems.org/\n  specs:\n) + | 
|  | 165 | +                           %(    activesupport (7.1.3.2)\n    shakapacker (8.2.0)\n      activesupport (>= 5.2)\n) | 
|  | 166 | +        allow(File).to receive(:read).with("Gemfile.lock").and_return(lockfile_content) | 
| 153 | 167 |       end | 
| 154 | 168 | 
 | 
| 155 | 169 |       it "adds a success message and checks gemfile" do | 
| 156 | 170 |         result = checker.check_shakapacker_configuration | 
| 157 | 171 |         expect(result).to be true | 
| 158 | 172 |         expect(checker.messages.any? do |msg| | 
| 159 |  | -                 msg[:type] == :success && msg[:content].include?("Shakapacker is properly configured") | 
|  | 173 | +                 msg[:type] == :success && msg[:content].include?("Shakapacker 8.2.0") | 
| 160 | 174 |                end).to be true | 
| 161 | 175 |         expect(checker).to have_received(:check_shakapacker_in_gemfile) | 
| 162 | 176 |       end | 
|  | 
| 223 | 237 |       end | 
| 224 | 238 | 
 | 
| 225 | 239 |       before do | 
| 226 |  | -        allow(File).to receive(:exist?).with("Gemfile").and_return(true) | 
| 227 |  | -        allow(File).to receive(:read).with("Gemfile").and_return(gemfile_content) | 
|  | 240 | +        gemfile_path = ENV["BUNDLE_GEMFILE"] || "Gemfile" | 
|  | 241 | +        allow(File).to receive(:exist?).with(gemfile_path).and_return(true) | 
|  | 242 | +        allow(File).to receive(:read).with(gemfile_path).and_return(gemfile_content) | 
| 228 | 243 |         stub_const("ReactOnRails::VERSION", "16.0.0") | 
| 229 | 244 |       end | 
| 230 | 245 | 
 | 
|  | 
| 244 | 259 |       end | 
| 245 | 260 | 
 | 
| 246 | 261 |       before do | 
| 247 |  | -        allow(File).to receive(:exist?).with("Gemfile").and_return(true) | 
| 248 |  | -        allow(File).to receive(:read).with("Gemfile").and_return(gemfile_content) | 
|  | 262 | +        gemfile_path = ENV["BUNDLE_GEMFILE"] || "Gemfile" | 
|  | 263 | +        allow(File).to receive(:exist?).with(gemfile_path).and_return(true) | 
|  | 264 | +        allow(File).to receive(:read).with(gemfile_path).and_return(gemfile_content) | 
| 249 | 265 |       end | 
| 250 | 266 | 
 | 
| 251 | 267 |       it "does not warn about exact versions" do | 
|  | 
| 308 | 324 |   describe "private methods" do | 
| 309 | 325 |     describe "#cli_exists?" do | 
| 310 | 326 |       it "returns true when command exists" do | 
| 311 |  | -        allow(checker).to receive(:system).with("which npm > /dev/null 2>&1").and_return(true) | 
|  | 327 | +        allow(Open3).to receive(:capture3).with("which", "npm") | 
|  | 328 | +                    .and_return(["", "", instance_double(Process::Status, success?: true)]) | 
| 312 | 329 |         expect(checker.send(:cli_exists?, "npm")).to be true | 
| 313 | 330 |       end | 
| 314 | 331 | 
 | 
| 315 | 332 |       it "returns false when command does not exist" do | 
| 316 |  | -        allow(checker).to receive(:system).with("which nonexistent > /dev/null 2>&1").and_return(false) | 
|  | 333 | +        allow(Open3).to receive(:capture3).with("which", "nonexistent") | 
|  | 334 | +                    .and_return(["", "", instance_double(Process::Status, success?: false)]) | 
| 317 | 335 |         expect(checker.send(:cli_exists?, "nonexistent")).to be false | 
| 318 | 336 |       end | 
| 319 | 337 |     end | 
|  | 
| 359 | 377 | 
 | 
| 360 | 378 |         messages = checker.messages | 
| 361 | 379 |         expect(messages.any? do |msg| | 
| 362 |  | -                 msg[:type] == :info && msg[:content].include?("React version: ^18.2.0") | 
| 363 |  | -               end).to be true | 
| 364 |  | -        expect(messages.any? do |msg| | 
| 365 |  | -                 msg[:type] == :info && msg[:content].include?("React DOM version: ^18.2.0") | 
|  | 380 | +                 msg[:type] == :success && msg[:content].include?("React ^18.2.0, React DOM ^18.2.0") | 
| 366 | 381 |                end).to be true | 
| 367 | 382 |       end | 
| 368 | 383 |     end | 
|  | 
0 commit comments