shakapacker 7.1.0 → 7.2.0.rc.0

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.
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