Skip to content

Commit f827d43

Browse files
justin808claude
andcommitted
Add missing Pro package RSpec test files
The Pro package CI was failing because the spec/react_on_rails_pro/ directory and spec/empty_spec.rb file were missing from the repository. These files contain the gem-level RSpec tests for the Pro package. This fixes the CI error: LoadError: cannot load such file -- spec/react_on_rails_pro Files added: - spec/empty_spec.rb - SimpleCov helper for test coverage - spec/react_on_rails_pro/ - Directory containing all Pro gem tests - assets_precompile_spec.rb - cache_spec.rb - configuration_spec.rb - request_spec.rb - stream_decorator_spec.rb - stream_request_spec.rb - stream_spec.rb - utils_spec.rb - react_on_rails_pro_spec.rb (version check) - fixtures/ and support/ directories with test helpers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 70a015e commit f827d43

20 files changed

+1951
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# frozen_string_literal: true
2+
3+
# This file is used to compel SimpleCov to output a new report based on its
4+
# cached data. Simply run rspec on this file to do so.
5+
require "simplecov"
6+
SimpleCov.command_name "empty_spec"
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "spec_helper"
4+
require_relative "../../lib/react_on_rails_pro/assets_precompile"
5+
6+
describe ReactOnRailsPro::AssetsPrecompile do
7+
describe ".zipped_bundles_filename" do
8+
it "returns a string dependant on bundles_cache_key" do
9+
instance = described_class.instance
10+
allow(instance).to receive(:bundles_cache_key).and_return("bundles_cache_key")
11+
12+
expect(instance.zipped_bundles_filename).to eq("precompile-cache.bundles_cache_key.production.gz")
13+
expect(instance).to have_received(:bundles_cache_key).once
14+
end
15+
end
16+
17+
describe ".zipped_bundles_filepath" do
18+
it "returns a pathname dependant on Rails.root & zipped_bundles_filename" do
19+
rails_stub = Module.new do
20+
def self.root
21+
Pathname.new(Dir.pwd)
22+
end
23+
end
24+
stub_const("Rails", rails_stub)
25+
26+
instance = described_class.instance
27+
allow(instance).to receive(:zipped_bundles_filename).and_return("zipped_bundles_filename")
28+
29+
expect(instance.zipped_bundles_filepath).to eq(Rails.root.join("tmp", "bundle_cache", "zipped_bundles_filename"))
30+
expect(instance).to have_received(:zipped_bundles_filename).once
31+
end
32+
end
33+
34+
describe ".bundles_cache_key" do
35+
it "calls ReactOnRailsPro::Utils.digest_of_globs with the union of " \
36+
"Shakapacker.config.source_path & ReactOnRailsPro.configuration.dependency_globs" do
37+
expected_parameters = %w[source_path dependency_globs]
38+
39+
source_path = instance_double(Pathname)
40+
allow(source_path).to receive(:join).and_return(expected_parameters.first)
41+
42+
webpacker_config = instance_double(Shakapacker::Configuration)
43+
allow(webpacker_config).to receive(:source_path).and_return(source_path)
44+
45+
allow(Shakapacker).to receive(:config).and_return(webpacker_config)
46+
47+
ror_pro_config = instance_double(ReactOnRailsPro::Configuration)
48+
49+
adapter = Module.new do
50+
def self.cache_keys
51+
%w[a b]
52+
end
53+
54+
def self.build(_filename)
55+
true
56+
end
57+
end
58+
59+
allow(ror_pro_config).to receive_messages(dependency_globs: [expected_parameters.last],
60+
remote_bundle_cache_adapter: adapter)
61+
62+
stub_const("ReactOnRailsPro::VERSION", "2.2.0")
63+
64+
allow(ReactOnRailsPro).to receive(:configuration).and_return(ror_pro_config)
65+
66+
allow(ReactOnRailsPro::Utils).to receive(:digest_of_globs).with(expected_parameters).and_return(Digest::MD5.new)
67+
68+
ENV["NODE_ENV"] = "production"
69+
70+
expect(described_class.instance.bundles_cache_key).to eq("0f923bb82b2fc3bfcbe53c6854d9ca72")
71+
end
72+
end
73+
74+
describe ".remote_bundle_cache_adapter" do
75+
it "raises an error if not assigned a module" do
76+
error_message = "config.remote_bundle_cache_adapter must have a module assigned"
77+
expect do
78+
described_class.instance.remote_bundle_cache_adapter
79+
end.to raise_error(ReactOnRailsPro::Error,
80+
error_message)
81+
end
82+
83+
it "returns configuration.remote_bundle_cache_adapter" do
84+
adapter = Module.new do
85+
def self.cache_keys
86+
%w[a b]
87+
end
88+
89+
def self.build(_filename)
90+
true
91+
end
92+
end
93+
94+
ror_pro_config = instance_double(ReactOnRailsPro::Configuration)
95+
allow(ror_pro_config).to receive(:remote_bundle_cache_adapter).and_return(adapter)
96+
allow(ReactOnRailsPro).to receive(:configuration).and_return(ror_pro_config)
97+
98+
expect(described_class.instance.remote_bundle_cache_adapter).to equal(adapter)
99+
end
100+
end
101+
102+
describe ".build_bundles" do
103+
it "triggers build without any parameters" do
104+
adapter = Module.new do
105+
def self.build(_filename)
106+
true
107+
end
108+
end
109+
110+
allow(described_class.instance).to receive(:remote_bundle_cache_adapter).and_return(adapter)
111+
112+
expect do
113+
described_class.instance.build_bundles
114+
end.to raise_error(ArgumentError,
115+
"wrong number of arguments (given 0, expected 1)")
116+
end
117+
end
118+
119+
describe ".build_or_fetch_bundles" do
120+
context "when ENV['DISABLE_PRECOMPILE_CACHE'] is not present" do
121+
before do
122+
ENV["DISABLE_PRECOMPILE_CACHE"] = nil
123+
end
124+
125+
it "tries to fetch cached bundles" do
126+
instance = described_class.instance
127+
128+
expect(instance).to receive(:fetch_and_unzip_cached_bundles).once.and_return(true)
129+
expect(instance).not_to receive(:build_bundles)
130+
expect(instance).not_to receive(:cache_bundles)
131+
132+
instance.build_or_fetch_bundles
133+
end
134+
135+
it "calls build_bundles & cache_bundles if cached bundles can't be fetched" do
136+
instance = described_class.instance
137+
138+
expect(instance).to receive(:fetch_and_unzip_cached_bundles).once
139+
expect(instance).to receive(:build_bundles).once
140+
allow(instance).to receive_messages(fetch_and_unzip_cached_bundles: false, build_bundles: nil,
141+
cache_bundles: nil)
142+
expect(instance).to receive(:cache_bundles).once
143+
144+
instance.build_or_fetch_bundles
145+
end
146+
end
147+
148+
context "when ENV['DISABLE_PRECOMPILE_CACHE'] is present" do
149+
before do
150+
ENV["DISABLE_PRECOMPILE_CACHE"] = "true"
151+
end
152+
153+
it "doesn't check for cached bundles" do
154+
instance = described_class.instance
155+
156+
allow(instance).to receive(:build_bundles).and_return(nil)
157+
expect(instance).to receive(:build_bundles).once
158+
expect(instance).not_to receive(:cache_bundles)
159+
expect(instance).not_to receive(:fetch_and_unzip_cached_bundles)
160+
161+
instance.build_or_fetch_bundles
162+
end
163+
end
164+
end
165+
166+
describe ".fetch_bundles" do
167+
it "calls remote_bundle_cache_adapter.fetch with zipped_bundles_filename" do
168+
adapter = Class.new do
169+
def self.fetch(*)
170+
true
171+
end
172+
end
173+
174+
adapter_double = class_double(adapter)
175+
allow(adapter_double).to receive(:fetch).and_return(true)
176+
177+
unique_variable = { unique_key: "a unique value" }
178+
179+
instance = described_class.instance
180+
allow(instance).to receive_messages(remote_bundle_cache_adapter: adapter_double,
181+
zipped_bundles_filename: unique_variable, zipped_bundles_filepath: "zipped_bundles_filepath")
182+
183+
allow(File).to receive(:binwrite).and_return(true)
184+
expect(File).to receive(:binwrite).once
185+
186+
expect(instance.fetch_bundles).to be_truthy
187+
188+
expect(adapter_double).to have_received(:fetch).with(unique_variable)
189+
end
190+
end
191+
192+
describe ".fetch_and_unzip_cached_bundles" do
193+
it "tries to fetch bundles if local cache is not detected" do
194+
allow(File).to receive(:exist?).and_return(false)
195+
196+
instance = described_class.instance
197+
allow(instance).to receive_messages(fetch_bundles: false, zipped_bundles_filepath: "a")
198+
199+
expect(instance.fetch_and_unzip_cached_bundles).to be(false)
200+
end
201+
202+
it "does not try to fetch remote cache if local cache exists" do
203+
allow(File).to receive(:exist?).and_return(true, false)
204+
205+
instance = described_class.instance
206+
expect(instance).not_to receive(:fetch_bundles)
207+
allow(instance).to receive(:zipped_bundles_filepath).and_return("a")
208+
209+
expect(instance.fetch_and_unzip_cached_bundles).to be(true)
210+
end
211+
212+
it "returns the same value as fetch_bundles" do
213+
allow(File).to receive(:exist?).and_return(false)
214+
215+
instance = described_class.instance
216+
allow(instance).to receive(:zipped_bundles_filepath).and_return("a")
217+
expect(instance).to receive(:fetch_bundles).once.and_return(true)
218+
219+
expect(instance.fetch_and_unzip_cached_bundles).to be(true)
220+
end
221+
end
222+
223+
describe ".cache_bundles" do
224+
it "calls remote_bundle_cache_adapter.upload with zipped_bundles_filepath" do
225+
webpacker_stub = Module.new do
226+
def self.public_output_path
227+
Dir.tmpdir
228+
end
229+
230+
def self.config
231+
self
232+
end
233+
end
234+
stub_const("Shakapacker", webpacker_stub)
235+
236+
rake_stub = Module.new do
237+
def self.sh(_string)
238+
true
239+
end
240+
end
241+
stub_const("Rake", rake_stub)
242+
243+
adapter = Class.new do
244+
def self.upload(*)
245+
true
246+
end
247+
end
248+
249+
adapter_double = class_double(adapter)
250+
allow(adapter_double).to receive(:upload).and_return(true)
251+
252+
zipped_bundles_filepath = Pathname.new(Dir.tmpdir).join("foobar")
253+
254+
instance = described_class.instance
255+
allow(instance).to receive_messages(remote_bundle_cache_adapter: adapter_double,
256+
zipped_bundles_filename: "zipped_bundles_filename", zipped_bundles_filepath: zipped_bundles_filepath, remove_extra_files_cache_dir: nil)
257+
258+
expect(instance.cache_bundles).to be_truthy
259+
260+
expect(adapter_double).to have_received(:upload).with(zipped_bundles_filepath)
261+
end
262+
end
263+
264+
describe ".copy_extra_files_to_cache_dir" do
265+
after do
266+
FileUtils.remove_dir("extra_files_cache_dir")
267+
end
268+
269+
it "copies the files in extra_files_to_cache to cache directory" do
270+
rails_stub = Module.new do
271+
def self.root
272+
Pathname.new(Dir.pwd)
273+
end
274+
end
275+
stub_const("Rails", rails_stub)
276+
277+
adapter = Module.new do
278+
def self.extra_files_to_cache
279+
[Pathname.new(Dir.pwd).join("Gemfile"),
280+
Pathname.new(Dir.pwd).join("lib", "react_on_rails_pro", "assets_precompile.rb")]
281+
end
282+
end
283+
284+
instance = described_class.instance
285+
286+
allow(instance).to receive_messages(remote_bundle_cache_adapter: adapter,
287+
extra_files_path: Pathname.new(Dir.pwd).join("extra_files_cache_dir"))
288+
copied_gemfile_path = Pathname.new(Dir.pwd).join("extra_files_cache_dir", "Gemfile")
289+
copied_assets_precompile_path = Pathname.new(Dir.pwd).join("extra_files_cache_dir",
290+
"lib---react_on_rails_pro---assets_precompile.rb")
291+
292+
instance.copy_extra_files_to_cache_dir
293+
294+
expect(copied_gemfile_path.exist?).to be(true)
295+
expect(copied_assets_precompile_path.exist?).to be(true)
296+
end
297+
end
298+
299+
describe ".extract_extra_files_from_cache_dir" do
300+
after do
301+
FileUtils.remove_dir("extra_files_extract_destination")
302+
end
303+
304+
it "extracts extra files from cache dir to their destination" do
305+
rails_stub = Module.new do
306+
def self.root
307+
Pathname.new(Dir.pwd)
308+
end
309+
end
310+
stub_const("Rails", rails_stub)
311+
312+
FileUtils.mkdir_p("extra_files_cache_dir")
313+
FileUtils.mkdir_p("extra_files_extract_destination")
314+
FileUtils.touch("extra_files_cache_dir/extra_files_extract_destination---extra_file_for_test.md")
315+
316+
instance = described_class.instance
317+
318+
allow(instance).to receive(:extra_files_path).and_return(Pathname.new(Dir.pwd).join("extra_files_cache_dir"))
319+
320+
instance.extract_extra_files_from_cache_dir
321+
322+
extracted_file_path = Pathname.new(Dir.pwd).join("extra_files_extract_destination", "extra_file_for_test.md")
323+
324+
expect(extracted_file_path.exist?).to be(true)
325+
end
326+
end
327+
end

0 commit comments

Comments
 (0)