shakapacker 6.5.5 → 6.5.6

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 (139) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +11 -7
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +21 -0
  4. data/.github/workflows/ruby.yml +3 -1
  5. data/.gitignore +3 -3
  6. data/.rspec +1 -0
  7. data/CHANGELOG.md +18 -2
  8. data/CONTRIBUTING.md +11 -1
  9. data/Gemfile.development_dependencies +3 -1
  10. data/README.md +41 -8
  11. data/Rakefile +4 -5
  12. data/gemfiles/Gemfile-rails-edge +1 -1
  13. data/gemfiles/Gemfile-rails.5.2.x +1 -1
  14. data/gemfiles/Gemfile-rails.6.0.x +1 -1
  15. data/gemfiles/Gemfile-rails.6.1.x +1 -1
  16. data/gemfiles/Gemfile-rails.7.0.x +1 -1
  17. data/lib/install/template.rb +21 -16
  18. data/lib/tasks/webpacker/compile.rake +5 -10
  19. data/lib/webpacker/helper.rb +20 -9
  20. data/lib/webpacker/version.rb +1 -1
  21. data/package/rules/__tests__/__utils__/webpack.js +50 -0
  22. data/package/rules/__tests__/babel.js +63 -0
  23. data/package/rules/__tests__/esbuild.js +64 -0
  24. data/package/rules/__tests__/index.js +0 -4
  25. data/package/rules/__tests__/swc.js +64 -0
  26. data/package/rules/babel.js +3 -14
  27. data/package/rules/esbuild.js +2 -13
  28. data/package/rules/jscommon.js +26 -0
  29. data/package/rules/swc.js +2 -13
  30. data/package/utils/helpers.js +1 -1
  31. data/package.json +8 -2
  32. data/spec/command_spec.rb +114 -0
  33. data/spec/compiler_spec.rb +57 -0
  34. data/spec/compiler_strategy_spec.rb +20 -0
  35. data/spec/configuration_spec.rb +281 -0
  36. data/{test/dev_server_runner_test.rb → spec/dev_server_runner_spec.rb} +30 -40
  37. data/spec/dev_server_spec.rb +45 -0
  38. data/spec/digest_strategy_spec.rb +33 -0
  39. data/{test/engine_rake_tasks_test.rb → spec/engine_rake_tasks_spec.rb} +17 -9
  40. data/spec/env_spec.rb +21 -0
  41. data/{test → spec}/fixtures/beta_package-lock.v1.json +0 -0
  42. data/{test → spec}/fixtures/beta_package-lock.v2.json +0 -0
  43. data/{test → spec}/fixtures/beta_package.json +0 -0
  44. data/{test → spec}/fixtures/beta_yarn.v1.lock +0 -0
  45. data/{test → spec}/fixtures/beta_yarn.v2.lock +0 -0
  46. data/{test → spec}/fixtures/git_url_package-lock.v1.json +0 -0
  47. data/{test → spec}/fixtures/git_url_package-lock.v2.json +0 -0
  48. data/{test → spec}/fixtures/git_url_package.json +0 -0
  49. data/{test → spec}/fixtures/git_url_yarn.v1.lock +0 -0
  50. data/{test → spec}/fixtures/git_url_yarn.v2.lock +0 -0
  51. data/{test → spec}/fixtures/github_url_package-lock.v1.json +0 -0
  52. data/{test → spec}/fixtures/github_url_package-lock.v2.json +0 -0
  53. data/{test → spec}/fixtures/github_url_package.json +0 -0
  54. data/{test → spec}/fixtures/github_url_yarn.v1.lock +0 -0
  55. data/{test → spec}/fixtures/github_url_yarn.v2.lock +0 -0
  56. data/{test → spec}/fixtures/relative_path_package-lock.v1.json +0 -0
  57. data/{test → spec}/fixtures/relative_path_package-lock.v2.json +0 -0
  58. data/{test → spec}/fixtures/relative_path_package.json +0 -0
  59. data/{test → spec}/fixtures/relative_path_yarn.v1.lock +0 -0
  60. data/{test → spec}/fixtures/relative_path_yarn.v2.lock +0 -0
  61. data/{test → spec}/fixtures/semver_caret_package-lock.v1.json +0 -0
  62. data/{test → spec}/fixtures/semver_caret_package-lock.v2.json +0 -0
  63. data/{test → spec}/fixtures/semver_caret_package.json +0 -0
  64. data/{test → spec}/fixtures/semver_caret_yarn.v1.lock +0 -0
  65. data/{test → spec}/fixtures/semver_caret_yarn.v2.lock +0 -0
  66. data/{test → spec}/fixtures/semver_exact_package-lock.v1.json +0 -0
  67. data/{test → spec}/fixtures/semver_exact_package-lock.v2.json +0 -0
  68. data/{test → spec}/fixtures/semver_exact_package.json +0 -0
  69. data/{test → spec}/fixtures/semver_exact_yarn.v1.lock +0 -0
  70. data/{test → spec}/fixtures/semver_exact_yarn.v2.lock +0 -0
  71. data/{test → spec}/fixtures/semver_tilde_package-lock.v1.json +0 -0
  72. data/{test → spec}/fixtures/semver_tilde_package-lock.v2.json +0 -0
  73. data/{test → spec}/fixtures/semver_tilde_package.json +0 -0
  74. data/{test → spec}/fixtures/semver_tilde_yarn.v1.lock +0 -0
  75. data/{test → spec}/fixtures/semver_tilde_yarn.v2.lock +0 -0
  76. data/{test → spec}/fixtures/without_package-lock.v1.json +0 -0
  77. data/{test → spec}/fixtures/without_package-lock.v2.json +0 -0
  78. data/{test → spec}/fixtures/without_package.json +0 -0
  79. data/{test → spec}/fixtures/without_yarn.v1.lock +0 -0
  80. data/{test → spec}/fixtures/without_yarn.v2.lock +0 -0
  81. data/spec/helper_spec.rb +241 -0
  82. data/spec/manifest_spec.rb +98 -0
  83. data/{test → spec}/mounted_app/Rakefile +0 -0
  84. data/{test → spec}/mounted_app/test/dummy/Rakefile +0 -0
  85. data/{test → spec}/mounted_app/test/dummy/bin/rails +0 -0
  86. data/{test → spec}/mounted_app/test/dummy/bin/rake +0 -0
  87. data/{test → spec}/mounted_app/test/dummy/config/application.rb +0 -0
  88. data/{test → spec}/mounted_app/test/dummy/config/environment.rb +0 -0
  89. data/{test → spec}/mounted_app/test/dummy/config/webpacker.yml +0 -0
  90. data/{test → spec}/mounted_app/test/dummy/config.ru +0 -0
  91. data/{test → spec}/mounted_app/test/dummy/package.json +0 -0
  92. data/spec/mtime_strategy_spec.rb +53 -0
  93. data/spec/rake_tasks_spec.rb +32 -0
  94. data/spec/spec_helper.rb +123 -0
  95. data/{test → spec}/test_app/Rakefile +0 -0
  96. data/{test → spec}/test_app/app/packs/entrypoints/application.js +0 -0
  97. data/{test → spec}/test_app/app/packs/entrypoints/generated/something.js +0 -0
  98. data/{test → spec}/test_app/app/packs/entrypoints/multi_entry.css +0 -0
  99. data/{test → spec}/test_app/app/packs/entrypoints/multi_entry.js +0 -0
  100. data/{test → spec}/test_app/bin/webpacker +0 -0
  101. data/{test → spec}/test_app/bin/webpacker-dev-server +0 -0
  102. data/{test → spec}/test_app/config/application.rb +0 -0
  103. data/{test → spec}/test_app/config/environment.rb +0 -0
  104. data/{test → spec}/test_app/config/initializers/inspect_autoload_paths.rb +0 -0
  105. data/{test → spec}/test_app/config/webpack/webpack.config.js +0 -0
  106. data/{test → spec}/test_app/config/webpacker.yml +0 -0
  107. data/{test → spec}/test_app/config/webpacker_css_extract_ignore_order_warnings.yml +0 -0
  108. data/{test → spec}/test_app/config/webpacker_defaults_fallback.yml +0 -0
  109. data/{test → spec}/test_app/config/webpacker_manifest_path.yml +0 -0
  110. data/{test → spec}/test_app/config/webpacker_nested_entries.yml +0 -0
  111. data/{test → spec}/test_app/config/webpacker_no_precompile.yml +0 -0
  112. data/{test → spec}/test_app/config/webpacker_other_location.yml +0 -0
  113. data/{test → spec}/test_app/config/webpacker_public_root.yml +0 -0
  114. data/{test → spec}/test_app/config.ru +0 -0
  115. data/{test → spec}/test_app/package.json +0 -0
  116. data/{test → spec}/test_app/public/packs/manifest.json +8 -0
  117. data/{test → spec}/test_app/some.config.js +0 -0
  118. data/{test → spec}/test_app/yarn.lock +0 -0
  119. data/spec/version_checker_spec.rb +950 -0
  120. data/{test/webpack_runner_test.rb → spec/webpack_runner_spec.rb} +12 -15
  121. data/spec/webpacker_spec.rb +39 -0
  122. data/yarn.lock +846 -844
  123. metadata +102 -187
  124. data/.github/ISSUE_TEMPLATE/feature-request.md +0 -18
  125. data/lib/tasks/yarn.rake +0 -44
  126. data/test/command_test.rb +0 -109
  127. data/test/compiler_strategy_test.rb +0 -27
  128. data/test/compiler_test.rb +0 -60
  129. data/test/configuration_test.rb +0 -186
  130. data/test/dev_server_test.rb +0 -47
  131. data/test/digest_strategy_test.rb +0 -33
  132. data/test/env_test.rb +0 -23
  133. data/test/helper_test.rb +0 -248
  134. data/test/manifest_test.rb +0 -89
  135. data/test/mtime_strategy_test.rb +0 -42
  136. data/test/rake_tasks_test.rb +0 -37
  137. data/test/test_helper.rb +0 -33
  138. data/test/version_checker_test.rb +0 -826
  139. data/test/webpacker_test.rb +0 -49
@@ -0,0 +1,64 @@
1
+ const path = require("path");
2
+ const {
3
+ app_javascript,
4
+ node_modules,
5
+ node_modules_included,
6
+ createTestCompiler,
7
+ createTrackLoader,
8
+ } = require("./__utils__/webpack");
9
+ const swcConfig = require("../swc");
10
+
11
+ jest.mock("../../config", () => {
12
+ const original = jest.requireActual("../../config");
13
+ return {
14
+ ...original,
15
+ webpack_loader: "swc",
16
+ additional_paths: [...original.additional_paths, "node_modules/included"],
17
+ };
18
+ });
19
+
20
+ const createWebpackConfig = (file, use) => {
21
+ return {
22
+ entry: { file },
23
+ module: {
24
+ rules: [
25
+ {
26
+ ...swcConfig,
27
+ use,
28
+ },
29
+ ],
30
+ },
31
+ output: {
32
+ path: "/",
33
+ filename: "scripts-bundled.js",
34
+ },
35
+ };
36
+ };
37
+
38
+ describe("swc", () => {
39
+ test("process source path", async () => {
40
+ const normalPath = `${app_javascript}/a.js`;
41
+ const [tracked, loader] = createTrackLoader();
42
+ const compiler = createTestCompiler(
43
+ createWebpackConfig(normalPath, loader)
44
+ );
45
+ await compiler.run();
46
+ expect(tracked[normalPath]).toBeTruthy();
47
+ });
48
+
49
+ test("exclude node_modules", async () => {
50
+ const ignored = `${node_modules}/a.js`;
51
+ const [tracked, loader] = createTrackLoader();
52
+ const compiler = createTestCompiler(createWebpackConfig(ignored, loader));
53
+ await compiler.run();
54
+ expect(tracked[ignored]).toBeUndefined();
55
+ });
56
+
57
+ test("explicitly included node_modules should be transpiled", async () => {
58
+ const included = `${node_modules_included}/a.js`;
59
+ const [tracked, loader] = createTrackLoader();
60
+ const compiler = createTestCompiler(createWebpackConfig(included, loader));
61
+ await compiler.run();
62
+ expect(tracked[included]).toBeTruthy();
63
+ });
64
+ });
@@ -1,24 +1,13 @@
1
- const { resolve } = require('path')
2
- const { realpathSync } = require('fs')
3
1
  const { loaderMatches } = require('../utils/helpers')
4
-
5
2
  const {
6
- source_path: sourcePath,
7
- additional_paths: additionalPaths,
8
3
  webpack_loader: webpackLoader
9
4
  } = require('../config')
10
5
  const { isProduction } = require('../env')
6
+ const jscommon = require('./jscommon')
11
7
 
12
8
  module.exports = loaderMatches(webpackLoader, 'babel', () => ({
13
9
  test: /\.(js|jsx|mjs|ts|tsx|coffee)?(\.erb)?$/,
14
- include: [sourcePath, ...additionalPaths].map((p) => {
15
- try {
16
- return realpathSync(p)
17
- } catch (e) {
18
- return resolve(p)
19
- }
20
- }),
21
- exclude: /node_modules/,
10
+ ...jscommon,
22
11
  use: [
23
12
  {
24
13
  loader: require.resolve('babel-loader'),
@@ -29,4 +18,4 @@ module.exports = loaderMatches(webpackLoader, 'babel', () => ({
29
18
  }
30
19
  }
31
20
  ]
32
- }))
21
+ }))
@@ -1,23 +1,12 @@
1
- const { resolve } = require('path')
2
- const { realpathSync } = require('fs')
3
1
  const { loaderMatches } = require('../utils/helpers')
4
2
  const { getEsbuildLoaderConfig } = require('../esbuild')
5
-
6
3
  const {
7
- source_path: sourcePath,
8
- additional_paths: additionalPaths,
9
4
  webpack_loader: webpackLoader
10
5
  } = require('../config')
6
+ const jscommon = require('./jscommon')
11
7
 
12
8
  module.exports = loaderMatches(webpackLoader, 'esbuild', () => ({
13
9
  test: /\.(ts|tsx|js|jsx|mjs|coffee)?(\.erb)?$/,
14
- include: [sourcePath, ...additionalPaths].map((p) => {
15
- try {
16
- return realpathSync(p)
17
- } catch (e) {
18
- return resolve(p)
19
- }
20
- }),
21
- exclude: /node_modules/,
10
+ ...jscommon,
22
11
  use: ({ resource }) => getEsbuildLoaderConfig(resource)
23
12
  }))
@@ -0,0 +1,26 @@
1
+ const { resolve } = require('path')
2
+ const { realpathSync } = require('fs')
3
+ const {
4
+ source_path: sourcePath,
5
+ additional_paths: additionalPaths
6
+ } = require('../config')
7
+
8
+ const inclusions = [sourcePath, ...additionalPaths].map(p => {
9
+ try {
10
+ return realpathSync(p)
11
+ } catch (e) {
12
+ return resolve(p)
13
+ }
14
+ })
15
+
16
+ module.exports = {
17
+ include: inclusions,
18
+ exclude: [
19
+ {
20
+ // exclude all node_modules from running through babel-loader
21
+ and: [resolve('node_modules')],
22
+ // Do not exclude inclusions, as otherwise these won't be transpiled
23
+ not: [...inclusions]
24
+ }
25
+ ]
26
+ }
data/package/rules/swc.js CHANGED
@@ -1,23 +1,12 @@
1
- const { resolve } = require('path')
2
- const { realpathSync } = require('fs')
3
1
  const { loaderMatches } = require('../utils/helpers')
4
2
  const { getSwcLoaderConfig } = require('../swc')
5
-
6
3
  const {
7
- source_path: sourcePath,
8
- additional_paths: additionalPaths,
9
4
  webpack_loader: webpackLoader
10
5
  } = require('../config')
6
+ const jscommon = require('./jscommon')
11
7
 
12
8
  module.exports = loaderMatches(webpackLoader, 'swc', () => ({
13
9
  test: /\.(ts|tsx|js|jsx|mjs|coffee)?(\.erb)?$/,
14
- include: [sourcePath, ...additionalPaths].map((p) => {
15
- try {
16
- return realpathSync(p)
17
- } catch (e) {
18
- return resolve(p)
19
- }
20
- }),
21
- exclude: /node_modules/,
10
+ ...jscommon,
22
11
  use: ({ resource }) => getSwcLoaderConfig(resource)
23
12
  }))
@@ -2,7 +2,7 @@ const isArray = (value) => Array.isArray(value)
2
2
  const isBoolean = (str) => /^true/.test(str) || /^false/.test(str)
3
3
  const chdirTestApp = () => {
4
4
  try {
5
- return process.chdir('test/test_app')
5
+ return process.chdir('spec/test_app')
6
6
  } catch (e) {
7
7
  return null
8
8
  }
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shakapacker",
3
- "version": "6.5.5",
3
+ "version": "6.5.6",
4
4
  "description": "Use webpack to manage app-like JavaScript modules in Rails",
5
5
  "main": "package/index.js",
6
6
  "files": [
@@ -40,14 +40,20 @@
40
40
  "eslint-plugin-import": "^2.24.2",
41
41
  "eslint-plugin-jsx-a11y": "^6.4.1",
42
42
  "eslint-plugin-react": "^7.26.0",
43
- "jest": "^27.2.1",
43
+ "jest": "^28.1.3",
44
+ "memory-fs": "^0.5.0",
44
45
  "swc-loader": "^0.1.15",
46
+ "thenify": "^3.3.1",
45
47
  "webpack": "^5.72.0",
46
48
  "webpack-assets-manifest": "^5.0.6",
47
49
  "webpack-merge": "^5.8.0"
48
50
  },
49
51
  "jest": {
50
52
  "testRegex": "(/__tests__/.*|(\\.|/))\\.jsx?$",
53
+ "testPathIgnorePatterns": [
54
+ "/__fixtures__/",
55
+ "/__utils__/"
56
+ ],
51
57
  "roots": [
52
58
  "<rootDir>/package"
53
59
  ]
@@ -0,0 +1,114 @@
1
+ describe "Command" do
2
+ before do
3
+ allow(Webpacker.logger).to receive(:info)
4
+ end
5
+
6
+ describe "#compile" do
7
+ it "returns success status when stale" do
8
+ expect(Webpacker.compiler).to receive(:stale?).and_return(true)
9
+ expect(Webpacker.compiler).to receive(:run_webpack).and_return(true)
10
+
11
+ expect(Webpacker.commands.compile).to be true
12
+ end
13
+
14
+ it "returns success status when fresh" do
15
+ expect(Webpacker.compiler).to receive(:stale?).and_return(false)
16
+
17
+ expect(Webpacker.commands.compile).to be true
18
+ end
19
+
20
+ it "returns failure status when stale" do
21
+ expect(Webpacker.compiler).to receive(:stale?).and_return(true)
22
+ expect(Webpacker.compiler).to receive(:run_webpack).and_return(false)
23
+
24
+ expect(Webpacker.commands.compile).to be false
25
+ end
26
+ end
27
+
28
+ describe "#clean" do
29
+ let(:now) { Time.parse("2021-01-01 12:34:56 UTC") }
30
+ let(:prev_files) do
31
+ # Test assets to be kept and deleted, path and mtime
32
+ {
33
+ # recent versions to be kept with Webpacker.commands.clean(count = 2)
34
+ "js/application-deadbeef.js" => now - 4000,
35
+ "js/common-deadbeee.js" => now - 4002,
36
+ "css/common-deadbeed.css" => now - 4004,
37
+ "media/images/logo-deadbeeb.css" => now - 4006,
38
+ "js/application-1eadbeef.js" => now - 8000,
39
+ "js/common-1eadbeee.js" => now - 8002,
40
+ "css/common-1eadbeed.css" => now - 8004,
41
+ "media/images/logo-1eadbeeb.css" => now - 8006,
42
+ # new files to be kept with Webpacker.commands.clean(age = 3600)
43
+ "js/brandnew-0001.js" => now,
44
+ "js/brandnew-0002.js" => now - 10,
45
+ "js/brandnew-0003.js" => now - 20,
46
+ "js/brandnew-0004.js" => now - 40,
47
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
48
+ end
49
+
50
+ let(:expired_files) do
51
+ {
52
+ # old files that are outside count = 2 or age = 3600 and to be deleted
53
+ "js/application-0eadbeef.js" => now - 9000,
54
+ "js/common-0eadbeee.js" => now - 9002,
55
+ "css/common-0eadbeed.css" => now - 9004,
56
+ "js/brandnew-0005.js" => now - 3640,
57
+ }.transform_keys { |path| "#{Webpacker.config.public_output_path}/#{path}" }
58
+ end
59
+
60
+ let(:all_files) { prev_files.merge(expired_files) }
61
+
62
+ let(:file_delete_mock) { double("File Delete") }
63
+ let(:file_mtime_stub) { Proc.new { |longpath| all_files[longpath] } }
64
+ let(:file_delete_stub) { Proc.new { |longpath| file_delete_mock.delete(longpath) } }
65
+
66
+ before :context do
67
+ @dir_glob_stub = Proc.new { |arg|
68
+ case arg
69
+ when "#{Webpacker.config.public_output_path}/**/*"
70
+ all_files.keys
71
+ else
72
+ []
73
+ end
74
+ }
75
+ end
76
+
77
+ it "works with nested hashes and without any compiled files" do
78
+ allow(File).to receive(:delete).and_return(true)
79
+ expect(Webpacker.commands.clean).to be true
80
+ end
81
+
82
+ it "deletes only and only expired versioned files if no parameter passed" do
83
+ all_files.keys.each do |longpath|
84
+ allow(file_delete_mock).to receive(:delete).with(longpath)
85
+ end
86
+
87
+ with_time_dir_and_files_stub do
88
+ expect(Webpacker.commands.clean).to be true
89
+
90
+ # Verify that only and only expired files are deleted
91
+ all_files.keys.each do |longpath|
92
+ if expired_files.has_key? longpath
93
+ expect(file_delete_mock).to have_received(:delete).with(longpath)
94
+ else
95
+ expect(file_delete_mock).to_not have_received(:delete).with(longpath)
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def with_time_dir_and_files_stub(&proc)
104
+ allow(Time).to receive(:now).and_return(now)
105
+ allow(Dir).to receive(:glob) { |arg| @dir_glob_stub.call(arg) }
106
+ allow(File).to receive(:directory?).and_return(false)
107
+ allow(File).to receive(:file?).and_return(true)
108
+ allow(File).to receive(:mtime) { |arg| file_mtime_stub.call(arg) }
109
+ allow(File).to receive(:delete) { |arg| file_delete_stub.call(arg) }
110
+
111
+ yield proc
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,57 @@
1
+ describe "Webpacker::Compiler" do
2
+ it "accepts custom environment variables" do
3
+ expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to be nil
4
+
5
+ Webpacker.compiler.env["FOO"] = "BAR"
6
+ expect(Webpacker.compiler.send(:webpack_env)["FOO"]).to eq "BAR"
7
+ ensure
8
+ Webpacker.compiler.env = {}
9
+ end
10
+
11
+ it "returns true when fresh" do
12
+ mocked_strategy = double("Strategy")
13
+ expect(mocked_strategy).to receive(:stale?).and_return(false)
14
+
15
+ expect(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
16
+
17
+ expect(Webpacker.compiler.compile).to be true
18
+ end
19
+
20
+ it "returns true and calls after_compile_hook on successful compile" do
21
+ mocked_strategy = spy("Strategy")
22
+ expect(mocked_strategy).to receive(:stale?).and_return(true)
23
+
24
+ allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
25
+
26
+ status = OpenStruct.new(success?: true)
27
+ allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
28
+
29
+ expect(Webpacker.compiler.compile).to be true
30
+ expect(mocked_strategy).to have_received(:after_compile_hook)
31
+ end
32
+
33
+ it "returns false and calls after_compile_hook on failed compile" do
34
+ mocked_strategy = spy("Strategy")
35
+ allow(mocked_strategy).to receive(:stale?).and_return(true)
36
+ allow(mocked_strategy).to receive(:after_compile_hook)
37
+
38
+ allow(Webpacker.compiler).to receive(:strategy).and_return(mocked_strategy)
39
+
40
+ status = OpenStruct.new(success?: false)
41
+ allow(Open3).to receive(:capture3).and_return([:sterr, :stdout, status])
42
+
43
+ expect(Webpacker.compiler.compile).to be false
44
+ expect(mocked_strategy).to have_received(:after_compile_hook)
45
+ end
46
+
47
+ it "accepts external env variables" do
48
+ expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"]).to be nil
49
+ expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"]).to be nil
50
+
51
+ ENV["WEBPACKER_ASSET_HOST"] = "foo.bar"
52
+ ENV["WEBPACKER_RELATIVE_URL_ROOT"] = "/baz"
53
+
54
+ expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_ASSET_HOST"]).to eq "foo.bar"
55
+ expect(Webpacker.compiler.send(:webpack_env)["WEBPACKER_RELATIVE_URL_ROOT"]).to eq "/baz"
56
+ end
57
+ end
@@ -0,0 +1,20 @@
1
+ describe "Webpacker::CompilerStrategy" do
2
+ describe "#from_config" do
3
+ it "returns and instance of MtimeStrategy when compiler_strategy is set to mtime" do
4
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("mtime")
5
+ expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::MtimeStrategy)
6
+ end
7
+
8
+ it "returns and instance of DigestStrategy when compiler_strategy is set to digest" do
9
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("digest")
10
+ expect(Webpacker::CompilerStrategy.from_config).to be_an_instance_of(Webpacker::DigestStrategy)
11
+ end
12
+
13
+ it "raise exception for unknown compiler_strategy in the config file" do
14
+ expected_error_message = "Unknown strategy 'other'. Available options are 'mtime' and 'digest'."
15
+ allow(Webpacker.config).to receive(:compiler_strategy).and_return("other")
16
+
17
+ expect { Webpacker::CompilerStrategy.from_config }.to raise_error(expected_error_message)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,281 @@
1
+ describe "Webpacker::Configuration" do
2
+ ROOT_PATH = Pathname.new(File.expand_path("test_app", __dir__))
3
+
4
+ context "with standard webpacker.yml" do
5
+ let(:config) do
6
+ Webpacker::Configuration.new(
7
+ root_path: ROOT_PATH,
8
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker.yml", __dir__)),
9
+ env: "production"
10
+ )
11
+ end
12
+
13
+ it "#source_path returns correct path" do
14
+ source_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs").to_s
15
+ expect(config.source_path.to_s).to eq source_path
16
+ end
17
+
18
+ it "#source_entry_path returns correct path" do
19
+ source_entry_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "entrypoints").to_s
20
+ expect(config.source_entry_path.to_s).to eq source_entry_path
21
+ end
22
+
23
+ it "#public_root_path returns correct path" do
24
+ public_root_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public").to_s
25
+ expect(config.public_path.to_s).to eq public_root_path
26
+ end
27
+
28
+ it "#public_output_path returns correct path" do
29
+ public_output_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs").to_s
30
+ expect(config.public_output_path.to_s).to eq public_output_path
31
+ end
32
+
33
+ it "#public_manifest_path returns correct path" do
34
+ public_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
35
+ expect(config.public_manifest_path.to_s).to eq public_manifest_path
36
+ end
37
+
38
+ it "#manifest_path returns correct path" do
39
+ manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/public/packs", "manifest.json").to_s
40
+ expect(config.manifest_path.to_s).to eq manifest_path
41
+ end
42
+
43
+ it "#cache_path returns correct path" do
44
+ cache_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/tmp/webpacker").to_s
45
+ expect(config.cache_path.to_s).to eq cache_path
46
+ end
47
+
48
+ it "#additional_paths returns correct path" do
49
+ expect(config.additional_paths).to eq ["app/assets", "/etc/yarn", "some.config.js", "app/elm"]
50
+ end
51
+
52
+ describe "#cache_manifest?" do
53
+ it "returns true in production environment" do
54
+ expect(config.cache_manifest?).to be true
55
+ end
56
+
57
+ it "returns false in developemnt environemnt" do
58
+ with_rails_env("development") do
59
+ expect(Webpacker.config.cache_manifest?).to be false
60
+ end
61
+ end
62
+
63
+ it "returns false in test environment" do
64
+ with_rails_env("test") do
65
+ expect(Webpacker.config.cache_manifest?).to be false
66
+ end
67
+ end
68
+ end
69
+
70
+ describe "#compile?" do
71
+ it "returns false in production environment" do
72
+ expect(config.compile?).to be false
73
+ end
74
+
75
+ it "returns true in developemnt environemnt" do
76
+ with_rails_env("development") do
77
+ expect(Webpacker.config.compile?).to be true
78
+ end
79
+ end
80
+
81
+ it "returns true in test environemnt" do
82
+ with_rails_env("test") do
83
+ expect(Webpacker.config.compile?).to be true
84
+ end
85
+ end
86
+ end
87
+
88
+ describe "#nested_entries?" do
89
+ it "returns false in production environment" do
90
+ expect(config.nested_entries?).to be false
91
+ end
92
+
93
+ it "returns false in development environment" do
94
+ with_rails_env("development") do
95
+ expect(Webpacker.config.nested_entries?).to be false
96
+ end
97
+ end
98
+
99
+ it "returns false in test environment" do
100
+ with_rails_env("test") do
101
+ expect(Webpacker.config.nested_entries?).to be false
102
+ end
103
+ end
104
+ end
105
+
106
+ describe "#ensure_consistent_versioning?" do
107
+ it "returns false in production environment" do
108
+ expect(config.ensure_consistent_versioning?).to be false
109
+ end
110
+
111
+ it "returns true in development environment" do
112
+ with_rails_env("development") do
113
+ expect(Webpacker.config.ensure_consistent_versioning?).to be true
114
+ end
115
+ end
116
+
117
+ it "returns false in test environment" do
118
+ with_rails_env("test") do
119
+ expect(Webpacker.config.ensure_consistent_versioning?).to be false
120
+ end
121
+ end
122
+ end
123
+
124
+ describe "#webpacker_precompile?" do
125
+ before :each do
126
+ ENV["WEBPACKER_PRECOMPILE"] = nil
127
+ end
128
+
129
+ subject { config.webpacker_precompile? }
130
+
131
+ it "returns true when WEBPACKER_PRECOMPILE is unset" do
132
+ is_expected.to be true
133
+ end
134
+
135
+ it "returns false when WEBPACKER_PRECOMPILE sets to no" do
136
+ ENV["WEBPACKER_PRECOMPILE"] = "no"
137
+ is_expected.to be false
138
+ end
139
+
140
+ it "returns true when WEBPACKER_PRECOMPILE sets to yes" do
141
+ ENV["WEBPACKER_PRECOMPILE"] = "yes"
142
+ is_expected.to be true
143
+ end
144
+
145
+ it "returns false when WEBPACKER_PRECOMPILE sets to false" do
146
+ ENV["WEBPACKER_PRECOMPILE"] = "false"
147
+ is_expected.to be false
148
+ end
149
+
150
+ it "returns true when WEBPACKER_PRECOMPILE sets to true" do
151
+ ENV["WEBPACKER_PRECOMPILE"] = "true"
152
+ is_expected.to be true
153
+ end
154
+
155
+ it "returns false when WEBPACKER_PRECOMPILE sets to n" do
156
+ ENV["WEBPACKER_PRECOMPILE"] = "n"
157
+ is_expected.to be false
158
+ end
159
+
160
+ it "returns true when WEBPACKER_PRECOMPILE sets to y" do
161
+ ENV["WEBPACKER_PRECOMPILE"] = "y"
162
+ is_expected.to be true
163
+ end
164
+
165
+ it "returns false when WEBPACKER_PRECOMPILE sets to f" do
166
+ ENV["WEBPACKER_PRECOMPILE"] = "f"
167
+ is_expected.to be false
168
+ end
169
+
170
+ it "returns true when WEBPACKER_PRECOMPILE sets to t" do
171
+ ENV["WEBPACKER_PRECOMPILE"] = "t"
172
+ is_expected.to be true
173
+ end
174
+ end
175
+ end
176
+
177
+ context "with webpacker config file containing public_output_path entry" do
178
+ config = Webpacker::Configuration.new(
179
+ root_path: ROOT_PATH,
180
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_public_root.yml", __dir__)),
181
+ env: "production"
182
+ )
183
+
184
+ it "#public_output_path returns correct path" do
185
+ expected_public_output_path = File.expand_path File.join(File.dirname(__FILE__), "public/packs").to_s
186
+ expect(config.public_output_path.to_s).to eq expected_public_output_path
187
+ end
188
+ end
189
+
190
+ context "with webpacker config file containing manifext_path entry" do
191
+ config = Webpacker::Configuration.new(
192
+ root_path: ROOT_PATH,
193
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_manifest_path.yml", __dir__)),
194
+ env: "production"
195
+ )
196
+
197
+ it "#manifest_path returns correct expected value" do
198
+ expected_manifest_path = File.expand_path File.join(File.dirname(__FILE__), "test_app/app/packs", "manifest.json").to_s
199
+ expect(config.manifest_path.to_s).to eq expected_manifest_path
200
+ end
201
+ end
202
+
203
+ context "with webpacker_precompile entry set to false" do
204
+ describe "#webpacker_precompile?" do
205
+ before :each do
206
+ ENV["WEBPACKER_PRECOMPILE"] = nil
207
+ end
208
+
209
+ let(:config) {
210
+ Webpacker::Configuration.new(
211
+ root_path: ROOT_PATH,
212
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_no_precompile.yml", __dir__)),
213
+ env: "production"
214
+ )
215
+ }
216
+
217
+ subject { config.webpacker_precompile? }
218
+
219
+ it "returns false with unset WEBPACKER_PRECOMPILE" do
220
+ expect(subject).to be false
221
+ end
222
+
223
+ it "returns true with WEBPACKER_PRECOMPILE set to true" do
224
+ ENV["WEBPACKER_PRECOMPILE"] = "true"
225
+ expect(subject).to be true
226
+ end
227
+
228
+ it "returns false with WEBPACKER_PRECOMPILE set to nil" do
229
+ ENV["WEBPACKER_PRECOMPILE"] = nil
230
+ expect(subject).to be false
231
+ end
232
+ end
233
+ end
234
+
235
+ context "with webpacker config file containing invalid path" do
236
+ config = Webpacker::Configuration.new(
237
+ root_path: ROOT_PATH,
238
+ config_path: Pathname.new(File.expand_path("./test_app/config/invalid_path.yml", __dir__)),
239
+ env: "default"
240
+ )
241
+
242
+ it "#webpacker_precompile? returns false" do
243
+ expect(config.webpacker_precompile?).to be false
244
+ end
245
+ end
246
+
247
+ context "with webpacker config file with defaults fallback" do
248
+ let(:config) do
249
+ Webpacker::Configuration.new(
250
+ root_path: ROOT_PATH,
251
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_defaults_fallback.yml", __dir__)),
252
+ env: "default"
253
+ )
254
+ end
255
+
256
+ it "#cache_manifest? falls back to 'default' config from bundled file" do
257
+ expect(config.cache_manifest?).to be false
258
+ end
259
+
260
+ it "#webpacker_precompile? uses 'default' config from custom file" do
261
+ expect(config.webpacker_precompile?).to be false
262
+ end
263
+ end
264
+
265
+ context "falls back to bundled production config for custom environments" do
266
+ let(:config) do
267
+ Webpacker::Configuration.new(
268
+ root_path: ROOT_PATH,
269
+ config_path: Pathname.new(File.expand_path("./test_app/config/webpacker_defaults_fallback.yml", __dir__)),
270
+ env: "staging"
271
+ )
272
+ end
273
+
274
+ it "#cache_manifest? fall back to 'production' config from bundled file" do
275
+ expect(config.cache_manifest?).to be true
276
+ end
277
+ it "#webpacker_precompile? use 'staging' config from custom file" do
278
+ expect(config.webpacker_precompile?).to be false
279
+ end
280
+ end
281
+ end