shakapacker 7.1.0 → 7.2.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/generator.yml +3 -0
  3. data/.github/workflows/ruby-backward-compatibility.yml +6 -0
  4. data/.github/workflows/ruby.yml +7 -0
  5. data/CHANGELOG.md +12 -6
  6. data/README.md +29 -3
  7. data/docs/v6_upgrade.md +1 -1
  8. data/lib/install/template.rb +56 -16
  9. data/lib/shakapacker/compiler.rb +5 -3
  10. data/lib/shakapacker/configuration.rb +8 -0
  11. data/lib/shakapacker/dev_server_runner.rb +11 -5
  12. data/lib/shakapacker/runner.rb +19 -1
  13. data/lib/shakapacker/utils/misc.rb +12 -0
  14. data/lib/shakapacker/version.rb +1 -1
  15. data/lib/shakapacker/webpack_runner.rb +12 -5
  16. data/lib/tasks/shakapacker/binstubs.rake +1 -1
  17. data/lib/tasks/shakapacker/check_manager.rake +27 -0
  18. data/lib/tasks/shakapacker/check_yarn.rake +2 -1
  19. data/lib/tasks/shakapacker/info.rake +20 -3
  20. data/lib/tasks/shakapacker/install.rake +1 -1
  21. data/lib/tasks/shakapacker/verify_install.rake +1 -1
  22. data/lib/tasks/shakapacker.rake +2 -2
  23. data/lib/tasks/webpacker/check_yarn.rake +1 -1
  24. data/package.json +2 -2
  25. data/shakapacker.gemspec +1 -0
  26. data/spec/backward_compatibility_specs/dev_server_runner_spec.rb +90 -30
  27. data/spec/backward_compatibility_specs/engine_rake_tasks_spec.rb +29 -7
  28. data/spec/backward_compatibility_specs/webpack_runner_spec.rb +44 -10
  29. data/spec/generator_specs/e2e_template/template.rb +31 -10
  30. data/spec/generator_specs/fake-bin/bun +10 -0
  31. data/spec/generator_specs/fake-bin/npm +10 -0
  32. data/spec/generator_specs/fake-bin/pnpm +10 -0
  33. data/spec/generator_specs/fake-bin/yarn +10 -0
  34. data/spec/generator_specs/generator_spec.rb +167 -17
  35. data/spec/mounted_app/package.json +1 -0
  36. data/spec/shakapacker/compiler_spec.rb +9 -5
  37. data/spec/shakapacker/configuration_spec.rb +48 -0
  38. data/spec/shakapacker/dev_server_runner_spec.rb +88 -29
  39. data/spec/shakapacker/engine_rake_tasks_spec.rb +27 -6
  40. data/spec/shakapacker/rake_tasks_spec.rb +6 -5
  41. data/spec/shakapacker/spec_helper_initializer.rb +18 -0
  42. data/spec/shakapacker/webpack_runner_spec.rb +44 -10
  43. data/spec/spec_helper.rb +2 -0
  44. data/spec/support/package_json_helpers.rb +16 -0
  45. metadata +26 -5
@@ -17,48 +17,108 @@ describe "DevServerRunner" do
17
17
 
18
18
  let(:test_app_path) { File.expand_path("webpacker_test_app", __dir__) }
19
19
 
20
- it "supports running via node modules" do
21
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
20
+ NODE_PACKAGE_MANAGERS.each do |fallback_manager|
21
+ context "when using package_json with #{fallback_manager} as the manager" do
22
+ with_use_package_json_gem(enabled: true, fallback_manager: fallback_manager)
22
23
 
23
- verify_command(cmd, use_node_modules: true)
24
- end
24
+ let(:package_json) { PackageJson.read(test_app_path) }
25
25
 
26
- it "supports running via yarn" do
27
- cmd = ["yarn", "webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
26
+ require "package_json"
28
27
 
29
- verify_command(cmd, use_node_modules: false)
30
- end
28
+ it "uses the expected package manager", unless: fallback_manager == "yarn_classic" do
29
+ cmd = package_json.manager.native_exec_command("webpack", ["serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"])
31
30
 
32
- it "passes on arguments" do
33
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--quiet"]
31
+ manager_name = fallback_manager.split("_")[0]
34
32
 
35
- verify_command(cmd, argv: (["--quiet"]))
36
- end
33
+ expect(cmd).to start_with(manager_name)
34
+ end
35
+
36
+ it "runs the command using the manager" do
37
+ cmd = package_json.manager.native_exec_command("webpack", ["serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"])
38
+
39
+ verify_command(cmd)
40
+ end
41
+
42
+ it "passes on arguments" do
43
+ cmd = package_json.manager.native_exec_command("webpack", ["serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--quiet"])
37
44
 
38
- it "supports the https flag" do
39
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--https"]
45
+ verify_command(cmd, argv: (["--quiet"]))
46
+ end
47
+
48
+ it "supports the https flag" do
49
+ cmd = package_json.manager.native_exec_command("webpack", ["serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--https"])
50
+
51
+ dev_server = double()
52
+ allow(dev_server).to receive(:host).and_return("localhost")
53
+ allow(dev_server).to receive(:port).and_return("3035")
54
+ allow(dev_server).to receive(:pretty?).and_return(false)
55
+ allow(dev_server).to receive(:https?).and_return(true)
56
+ allow(dev_server).to receive(:hmr?).and_return(false)
57
+
58
+ allow(Shakapacker::DevServer).to receive(:new) do
59
+ verify_command(cmd, argv: (["--https"]))
60
+ end.and_return(dev_server)
61
+ end
62
+
63
+ it "accepts environment variables" do
64
+ cmd = package_json.manager.native_exec_command("webpack", ["serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"])
65
+ env = Webpacker::Compiler.env.dup
40
66
 
41
- dev_server = double()
42
- allow(dev_server).to receive(:host).and_return("localhost")
43
- allow(dev_server).to receive(:port).and_return("3035")
44
- allow(dev_server).to receive(:pretty?).and_return(false)
45
- allow(dev_server).to receive(:https?).and_return(true)
46
- allow(dev_server).to receive(:hmr?).and_return(false)
67
+ # ENV["WEBPACKER_CONFIG"] is the interface and env["SHAKAPACKER_CONFIG"] is internal
68
+ ENV["WEBPACKER_CONFIG"] = env["SHAKAPACKER_CONFIG"] = "#{test_app_path}/config/webpacker_other_location.yml"
69
+ env["WEBPACK_SERVE"] = "true"
47
70
 
48
- allow(Webpacker::DevServer).to receive(:new) do
49
- verify_command(cmd, argv: (["--https"]))
50
- end.and_return(dev_server)
71
+ verify_command(cmd, env: env)
72
+ end
73
+ end
51
74
  end
52
75
 
53
- it "accepts environment variables" do
54
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
55
- env = Webpacker::Compiler.env.dup
76
+ context "when not using package_json" do
77
+ with_use_package_json_gem(enabled: false)
56
78
 
57
- # ENV["WEBPACKER_CONFIG"] is the interface and env["SHAKAPACKER_CONFIG"] is internal
58
- ENV["WEBPACKER_CONFIG"] = env["SHAKAPACKER_CONFIG"] = "#{test_app_path}/config/webpacker_other_location.yml"
59
- env["WEBPACK_SERVE"] = "true"
79
+ it "supports running via node modules" do
80
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
60
81
 
61
- verify_command(cmd, env: env)
82
+ verify_command(cmd, use_node_modules: true)
83
+ end
84
+
85
+ it "supports running via yarn" do
86
+ cmd = ["yarn", "webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
87
+
88
+ verify_command(cmd, use_node_modules: false)
89
+ end
90
+
91
+ it "passes on arguments" do
92
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--quiet"]
93
+
94
+ verify_command(cmd, argv: (["--quiet"]))
95
+ end
96
+
97
+ it "supports the https flag" do
98
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--https"]
99
+
100
+ dev_server = double()
101
+ allow(dev_server).to receive(:host).and_return("localhost")
102
+ allow(dev_server).to receive(:port).and_return("3035")
103
+ allow(dev_server).to receive(:pretty?).and_return(false)
104
+ allow(dev_server).to receive(:https?).and_return(true)
105
+ allow(dev_server).to receive(:hmr?).and_return(false)
106
+
107
+ allow(Shakapacker::DevServer).to receive(:new) do
108
+ verify_command(cmd, argv: (["--https"]))
109
+ end.and_return(dev_server)
110
+ end
111
+
112
+ it "accepts environment variables" do
113
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "serve", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
114
+ env = Webpacker::Compiler.env.dup
115
+
116
+ # ENV["WEBPACKER_CONFIG"] is the interface and env["SHAKAPACKER_CONFIG"] is internal
117
+ ENV["WEBPACKER_CONFIG"] = env["SHAKAPACKER_CONFIG"] = "#{test_app_path}/config/webpacker_other_location.yml"
118
+ env["WEBPACK_SERVE"] = "true"
119
+
120
+ verify_command(cmd, env: env)
121
+ end
62
122
  end
63
123
 
64
124
  private
@@ -9,16 +9,38 @@ describe "EngineRakeTasks" do
9
9
  remove_webpack_binstubs
10
10
  end
11
11
 
12
- it "mounts app:webpacker task successfully" do
13
- output = Dir.chdir(mounted_app_path) { `rake -T` }
12
+ NODE_PACKAGE_MANAGERS.each do |fallback_manager|
13
+ context "when using package_json with #{fallback_manager} as the manager" do
14
+ with_use_package_json_gem(enabled: true, fallback_manager: fallback_manager)
14
15
 
15
- expect(output).to match /app:webpacker.+DEPRECATED/
16
- expect(output).to match /app:webpacker:binstubs.+DEPRECATED/
16
+ it "mounts app:webpacker task successfully" do
17
+ output = Dir.chdir(mounted_app_path) { `rake -T` }
18
+
19
+ expect(output).to match /app:webpacker.+DEPRECATED/
20
+ expect(output).to match /app:webpacker:binstubs.+DEPRECATED/
21
+ end
22
+
23
+ it "only adds expected files to bin directory when binstubs is run" do
24
+ Dir.chdir(mounted_app_path) { `bundle exec rake app:webpacker:binstubs` }
25
+ expected_binstub_paths.each { |path| expect(File.exist?(path)).to be true }
26
+ end
27
+ end
17
28
  end
18
29
 
19
- it "only adds expected files to bin directory when binstubs is run" do
20
- Dir.chdir(mounted_app_path) { `bundle exec rake app:webpacker:binstubs` }
21
- expected_binstub_paths.each { |path| expect(File.exist?(path)).to be true }
30
+ context "when not using package_json" do
31
+ with_use_package_json_gem(enabled: false)
32
+
33
+ it "mounts app:webpacker task successfully" do
34
+ output = Dir.chdir(mounted_app_path) { `rake -T` }
35
+
36
+ expect(output).to match /app:webpacker.+DEPRECATED/
37
+ expect(output).to match /app:webpacker:binstubs.+DEPRECATED/
38
+ end
39
+
40
+ it "only adds expected files to bin directory when binstubs is run" do
41
+ Dir.chdir(mounted_app_path) { `bundle exec rake app:webpacker:binstubs` }
42
+ expected_binstub_paths.each { |path| expect(File.exist?(path)).to be true }
43
+ end
22
44
  end
23
45
 
24
46
  private
@@ -15,22 +15,56 @@ describe "WebpackRunner" do
15
15
 
16
16
  let(:test_app_path) { File.expand_path("./webpacker_test_app", __dir__) }
17
17
 
18
- it "supports running via node_modules" do
19
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
18
+ NODE_PACKAGE_MANAGERS.each do |fallback_manager|
19
+ context "when using package_json with #{fallback_manager} as the manager" do
20
+ with_use_package_json_gem(enabled: true, fallback_manager: fallback_manager)
20
21
 
21
- verify_command(cmd, use_node_modules: true)
22
- end
22
+ let(:package_json) { PackageJson.read(test_app_path) }
23
+
24
+ require "package_json"
25
+
26
+ it "uses the expected package manager", unless: fallback_manager == "yarn_classic" do
27
+ cmd = package_json.manager.native_exec_command("webpack", ["--config", "#{test_app_path}/config/webpack/webpack.config.js"])
28
+
29
+ manager_name = fallback_manager.split("_")[0]
30
+
31
+ expect(cmd).to start_with(manager_name)
32
+ end
33
+
34
+ it "runs the command using the manager" do
35
+ cmd = package_json.manager.native_exec_command("webpack", ["--config", "#{test_app_path}/config/webpack/webpack.config.js"])
23
36
 
24
- it "supports running via yarn" do
25
- cmd = ["yarn", "webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
37
+ verify_command(cmd)
38
+ end
26
39
 
27
- verify_command(cmd, use_node_modules: false)
40
+ it "passes on arguments" do
41
+ cmd = package_json.manager.native_exec_command("webpack", ["--config", "#{test_app_path}/config/webpack/webpack.config.js", "--watch"])
42
+
43
+ verify_command(cmd, argv: (["--watch"]))
44
+ end
45
+ end
28
46
  end
29
47
 
30
- it "passes on arguments" do
31
- cmd = ["#{test_app_path}/node_modules/.bin/webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--watch"]
48
+ context "when not using package_json" do
49
+ with_use_package_json_gem(enabled: false)
50
+
51
+ it "supports running via node_modules" do
52
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
53
+
54
+ verify_command(cmd, use_node_modules: true)
55
+ end
56
+
57
+ it "supports running via yarn" do
58
+ cmd = ["yarn", "webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js"]
32
59
 
33
- verify_command(cmd, argv: ["--watch"])
60
+ verify_command(cmd, use_node_modules: false)
61
+ end
62
+
63
+ it "passes on arguments" do
64
+ cmd = ["#{test_app_path}/node_modules/.bin/webpack", "--config", "#{test_app_path}/config/webpack/webpack.config.js", "--watch"]
65
+
66
+ verify_command(cmd, argv: ["--watch"])
67
+ end
34
68
  end
35
69
 
36
70
  private
@@ -1,13 +1,34 @@
1
- # install react
2
- system("yarn add react react-dom @babel/preset-react")
3
-
4
- # update webpack presets for react
5
- package_json_path = Rails.root.join("./package.json")
6
- insert_into_file(
7
- package_json_path,
8
- %( "@babel/preset-react",\n),
9
- after: /"presets": \[\n/
10
- )
1
+ require "shakapacker/utils/misc"
2
+
3
+ if Shakapacker::Utils::Misc.use_package_json_gem
4
+ Shakapacker::Utils::Misc.require_package_json_gem
5
+
6
+ package_json = PackageJson.new
7
+
8
+ # install react
9
+ package_json.manager.add(["react", "react-dom", "@babel/preset-react"])
10
+
11
+ # update webpack presets for react
12
+ package_json.merge! do |pj|
13
+ babel = pj.fetch("babel", {})
14
+
15
+ babel["presets"] ||= []
16
+ babel["presets"].unshift("@babel/preset-react")
17
+
18
+ { "babel" => babel }
19
+ end
20
+ else
21
+ # install react
22
+ system("yarn add react react-dom @babel/preset-react")
23
+
24
+ # update webpack presets for react
25
+ package_json_path = Rails.root.join("./package.json")
26
+ insert_into_file(
27
+ package_json_path,
28
+ %( "@babel/preset-react",\n),
29
+ after: /"presets": \[\n/
30
+ )
31
+ end
11
32
 
12
33
  # install rspec-rails
13
34
  system("bundle add rspec-rails --group development,test")
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ binary = "bun"
4
+ major_version = "1"
5
+
6
+ unless ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] == binary
7
+ raise StandardError, "(#{binary}) this is not the package manager you're looking for..."
8
+ end
9
+
10
+ exec("npx", "-y", "#{binary}@#{major_version}", *ARGV)
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ binary = "npm"
4
+ major_version = "9"
5
+
6
+ unless ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] == binary
7
+ raise StandardError, "(#{binary}) this is not the package manager you're looking for..."
8
+ end
9
+
10
+ exec("npx", "-y", "#{binary}@#{major_version}", *ARGV)
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ binary = "pnpm"
4
+ major_version = "8"
5
+
6
+ unless ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] == binary
7
+ raise StandardError, "(#{binary}) this is not the package manager you're looking for..."
8
+ end
9
+
10
+ exec("npx", "-y", "#{binary}@#{major_version}", *ARGV)
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ binary = "yarn"
4
+ major_version = "1"
5
+
6
+ unless ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] == "#{binary}_classic"
7
+ raise StandardError, "(#{binary}) this is not the package manager you're looking for..."
8
+ end
9
+
10
+ exec("npx", "-y", "#{binary}@#{major_version}", *ARGV)
@@ -3,6 +3,7 @@ require "rake"
3
3
  require "json"
4
4
  require "shakapacker/utils/misc"
5
5
  require "shakapacker/utils/version_syntax_converter"
6
+ require "package_json"
6
7
 
7
8
  GEM_ROOT = Pathname.new(File.expand_path("../../..", __FILE__))
8
9
  SPEC_PATH = Pathname.new(File.expand_path("../", __FILE__))
@@ -12,13 +13,13 @@ TEMP_RAILS_APP_PATH = SPEC_PATH.join("temp-rails-app")
12
13
  describe "Generator" do
13
14
  before :all do
14
15
  # Don't use --skip-git because we want .gitignore file to exist in the project
15
- sh_in_dir(SPEC_PATH, %(
16
+ sh_in_dir({}, SPEC_PATH, %(
16
17
  rails new base-rails-app --skip-javascript --skip-bundle --skip-spring
17
18
  rm -rf base-rails-app/.git
18
19
  ))
19
20
 
20
21
  Bundler.with_unbundled_env do
21
- sh_in_dir(BASE_RAILS_APP_PATH, %(
22
+ sh_in_dir({}, BASE_RAILS_APP_PATH, %(
22
23
  gem update bundler
23
24
  bundle add shakapacker --path "#{GEM_ROOT}"
24
25
  ))
@@ -31,12 +32,144 @@ describe "Generator" do
31
32
  end
32
33
 
33
34
  describe "shakapacker:install" do
34
- context "in a normal Rails project" do
35
+ # TODO: ideally "yarn_berry" should be here too, but it requires more complex setup
36
+ NODE_PACKAGE_MANAGERS.reject { |fm| fm == "yarn_berry" }.each do |fallback_manager|
37
+ context "when using package_json with #{fallback_manager} as the manager" do
38
+ before :all do
39
+ sh_opts = { fallback_manager: fallback_manager }
40
+
41
+ sh_in_dir(sh_opts, SPEC_PATH, "cp -r '#{BASE_RAILS_APP_PATH}' '#{TEMP_RAILS_APP_PATH}'")
42
+
43
+ Bundler.with_unbundled_env do
44
+ sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "FORCE=true bundle exec rails shakapacker:install")
45
+ end
46
+ end
47
+
48
+ after :all do
49
+ Dir.chdir(SPEC_PATH)
50
+ FileUtils.rm_rf(TEMP_RAILS_APP_PATH)
51
+ end
52
+
53
+ it "creates `config/shakapacker.yml`" do
54
+ config_file_relative_path = "config/shakapacker.yml"
55
+ actual_content = read(path_in_the_app(config_file_relative_path))
56
+ expected_content = read(path_in_the_gem(config_file_relative_path))
57
+
58
+ expect(actual_content).to eq expected_content
59
+ end
60
+
61
+ it "replaces package.json with the template file" do
62
+ package_json = PackageJson.read(path_in_the_app)
63
+
64
+ expect(package_json.fetch("name", "")).to eq("app")
65
+ end
66
+
67
+ it "creates webpack config directory and its files" do
68
+ expected_files = [
69
+ "webpack.config.js"
70
+ ]
71
+
72
+ Dir.chdir(path_in_the_app("config/webpack")) do
73
+ existing_files_in_config_webpack_dir = Dir.glob("*")
74
+ expect(existing_files_in_config_webpack_dir).to eq expected_files
75
+ end
76
+ end
77
+
78
+ it "adds binstubs" do
79
+ expected_binstubs = []
80
+ Dir.chdir(File.join(GEM_ROOT, "lib/install/bin")) do
81
+ expected_binstubs = Dir.glob("bin/*")
82
+ end
83
+
84
+ Dir.chdir(File.join(TEMP_RAILS_APP_PATH, "bin")) do
85
+ actual_binstubs = Dir.glob("*")
86
+ expect(actual_binstubs).to include(*expected_binstubs)
87
+ end
88
+ end
89
+
90
+ it "modifies .gitignore" do
91
+ actual_content = read(path_in_the_app(".gitignore"))
92
+
93
+ expect(actual_content).to match ".yarn-integrity"
94
+ end
95
+
96
+ it 'adds <%= javascript_pack_tag "application" %>' do
97
+ actual_content = read(path_in_the_app("app/views/layouts/application.html.erb"))
98
+
99
+ expect(actual_content).to match '<%= javascript_pack_tag "application" %>'
100
+ end
101
+
102
+ it "updates `bin/setup`" do
103
+ package_json = PackageJson.read(path_in_the_app)
104
+ cmd = package_json.manager.native_install_command.join(" ")
105
+
106
+ setup_file_content = read(path_in_the_app("bin/setup"))
107
+
108
+ expect(setup_file_content).to match %r(^\s*system!\(['"]#{cmd}['"]\))
109
+ end
110
+
111
+ it "adds relevant shakapacker version in package.json depending on gem version" do
112
+ npm_version = Shakapacker::Utils::VersionSyntaxConverter.new.rubygem_to_npm(Shakapacker::VERSION)
113
+
114
+ package_json = PackageJson.read(path_in_the_app)
115
+ actual_version = package_json.fetch("dependencies", {})["shakapacker"]
116
+
117
+ expect(actual_version).to eq(npm_version)
118
+ end
119
+
120
+ it "adds Shakapacker peer dependencies to package.json" do
121
+ package_json = PackageJson.read(path_in_the_app)
122
+ actual_dependencies = package_json.fetch("dependencies", {}).keys
123
+
124
+ expected_dependencies = %w(
125
+ @babel/core
126
+ @babel/plugin-transform-runtime
127
+ @babel/preset-env
128
+ @babel/runtime
129
+ babel-loader
130
+ compression-webpack-plugin
131
+ terser-webpack-plugin
132
+ webpack
133
+ webpack-assets-manifest
134
+ webpack-cli
135
+ webpack-merge
136
+ )
137
+
138
+ expect(actual_dependencies).to include(*expected_dependencies)
139
+ end
140
+
141
+ it "adds Shakapacker peer dev dependencies to package.json" do
142
+ package_json = PackageJson.read(path_in_the_app)
143
+ actual_dev_dependencies = package_json.fetch("devDependencies", {}).keys
144
+
145
+ expected_dev_dependencies = %w(
146
+ webpack-dev-server
147
+ )
148
+
149
+ expect(actual_dev_dependencies).to include(*expected_dev_dependencies)
150
+ end
151
+
152
+ context "with a basic react app setup" do
153
+ it "passes the test for rendering react component on the page" do
154
+ sh_opts = { fallback_manager: fallback_manager }
155
+
156
+ Bundler.with_unbundled_env do
157
+ sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "./bin/rails app:template LOCATION=../e2e_template/template.rb")
158
+ expect(sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "bundle exec rspec")).to be_truthy
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ context "when not using package_json" do
35
166
  before :all do
36
- sh_in_dir(SPEC_PATH, "cp -r '#{BASE_RAILS_APP_PATH}' '#{TEMP_RAILS_APP_PATH}'")
167
+ sh_opts = { fallback_manager: nil }
168
+
169
+ sh_in_dir(sh_opts, SPEC_PATH, "cp -r '#{BASE_RAILS_APP_PATH}' '#{TEMP_RAILS_APP_PATH}'")
37
170
 
38
171
  Bundler.with_unbundled_env do
39
- sh_in_dir(TEMP_RAILS_APP_PATH, "FORCE=true bundle exec rails shakapacker:install")
172
+ sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "FORCE=true bundle exec rails shakapacker:install")
40
173
  end
41
174
  end
42
175
 
@@ -53,10 +186,10 @@ describe "Generator" do
53
186
  expect(actual_content).to eq expected_content
54
187
  end
55
188
 
56
- it "replaces package.json with the template file" do
57
- actual_content = read(path_in_the_app("package.json"))
189
+ it "replaces package.json with template file" do
190
+ package_json = PackageJson.read(path_in_the_app)
58
191
 
59
- expect(actual_content).to match /"name": "app",/
192
+ expect(package_json.fetch("name", "")).to eq("app")
60
193
  end
61
194
 
62
195
  it "creates the webpack config directory and its files" do
@@ -104,14 +237,15 @@ describe "Generator" do
104
237
  it "uses the shakapacker version in package.json depending on gem version" do
105
238
  npm_version = Shakapacker::Utils::VersionSyntaxConverter.new.rubygem_to_npm(Shakapacker::VERSION)
106
239
 
107
- actual_content = read(path_in_the_app("package.json"))
240
+ package_json = PackageJson.read(path_in_the_app)
241
+ actual_version = package_json.fetch("dependencies", {})["shakapacker"]
108
242
 
109
- expect(actual_content).to match /"shakapacker": "#{npm_version}",/
243
+ expect(actual_version).to eq(npm_version)
110
244
  end
111
245
 
112
246
  it "adds Shakapacker peer dependencies to package.json" do
113
- package_json = JSON.parse(File.read(path_in_the_app("package.json")))
114
- actual_dependencies = package_json["dependencies"]&.keys
247
+ package_json = PackageJson.read(path_in_the_app)
248
+ actual_dependencies = package_json.fetch("dependencies", {}).keys
115
249
 
116
250
  expected_dependencies = %w(
117
251
  @babel/core
@@ -131,8 +265,8 @@ describe "Generator" do
131
265
  end
132
266
 
133
267
  it "adds Shakapacker peer dev dependencies to package.json" do
134
- package_json = JSON.parse(File.read(path_in_the_app("package.json")))
135
- actual_dev_dependencies = package_json["devDependencies"]&.keys
268
+ package_json = PackageJson.read(path_in_the_app)
269
+ actual_dev_dependencies = package_json.fetch("devDependencies", {}).keys
136
270
 
137
271
  expected_dev_dependencies = %w(
138
272
  webpack-dev-server
@@ -143,10 +277,12 @@ describe "Generator" do
143
277
 
144
278
  context "with a basic react app setup" do
145
279
  it "passes the test for rendering react component on the page" do
280
+ sh_opts = { fallback_manager: nil }
281
+
146
282
  Bundler.with_unbundled_env do
147
- sh_in_dir(TEMP_RAILS_APP_PATH, "./bin/rails app:template LOCATION=../e2e_template/template.rb")
283
+ sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "./bin/rails app:template LOCATION=../e2e_template/template.rb")
148
284
 
149
- expect(sh_in_dir(TEMP_RAILS_APP_PATH, "bundle exec rspec")).to be_truthy
285
+ expect(sh_in_dir(sh_opts, TEMP_RAILS_APP_PATH, "bundle exec rspec")).to be_truthy
150
286
  end
151
287
  end
152
288
  end
@@ -167,7 +303,21 @@ describe "Generator" do
167
303
  File.read(path)
168
304
  end
169
305
 
170
- def sh_in_dir(dir, *shell_commands)
306
+ def sort_out_package_json(opts)
307
+ ENV["PATH"] = "#{SPEC_PATH}/fake-bin:#{ENV["PATH"]}"
308
+
309
+ if opts[:fallback_manager].nil?
310
+ ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] = "yarn_classic"
311
+ ENV["SHAKAPACKER_USE_PACKAGE_JSON_GEM"] = "false"
312
+ else
313
+ ENV["SHAKAPACKER_EXPECTED_PACKAGE_MANGER"] = opts[:fallback_manager]
314
+ ENV["SHAKAPACKER_USE_PACKAGE_JSON_GEM"] = "true"
315
+ ENV["PACKAGE_JSON_FALLBACK_MANAGER"] = opts[:fallback_manager]
316
+ end
317
+ end
318
+
319
+ def sh_in_dir(opts, dir, *shell_commands)
320
+ sort_out_package_json(opts)
171
321
  Shakapacker::Utils::Misc.sh_in_dir(dir, *shell_commands)
172
322
  end
173
323
  end
@@ -0,0 +1 @@
1
+ {}
@@ -50,10 +50,14 @@ describe "Shakapacker::Compiler" do
50
50
  expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_ASSET_HOST"]).to be nil
51
51
  expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_RELATIVE_URL_ROOT"]).to be nil
52
52
 
53
- ENV["SHAKAPACKER_ASSET_HOST"] = "foo.bar"
54
- ENV["SHAKAPACKER_RELATIVE_URL_ROOT"] = "/baz"
55
-
56
- expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_ASSET_HOST"]).to eq "foo.bar"
57
- expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_RELATIVE_URL_ROOT"]).to eq "/baz"
53
+ custom_env_variables = {
54
+ "SHAKAPACKER_ASSET_HOST" => "foo.bar",
55
+ "SHAKAPACKER_RELATIVE_URL_ROOT" => "/baz"
56
+ }
57
+
58
+ with_env_variable(custom_env_variables) do
59
+ expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_ASSET_HOST"]).to eq "foo.bar"
60
+ expect(Shakapacker.compiler.send(:webpack_env)["SHAKAPACKER_RELATIVE_URL_ROOT"]).to eq "/baz"
61
+ end
58
62
  end
59
63
  end