vite_rails 1.0.4 → 1.0.9

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/CONTRIBUTING.md +0 -1
  4. data/README.md +27 -65
  5. data/lib/install/javascript/entrypoints/application.js +8 -4
  6. data/lib/install/template.rb +1 -1
  7. data/lib/tasks/vite/build.rake +2 -6
  8. data/lib/tasks/vite/clean.rake +1 -3
  9. data/lib/tasks/vite/info.rake +0 -1
  10. data/lib/tasks/vite/verify_install.rake +3 -3
  11. data/lib/vite_rails.rb +19 -25
  12. data/lib/vite_rails/builder.rb +11 -4
  13. data/lib/vite_rails/commands.rb +50 -10
  14. data/lib/vite_rails/config.rb +35 -23
  15. data/lib/vite_rails/dev_server_proxy.rb +27 -16
  16. data/lib/vite_rails/helper.rb +36 -8
  17. data/lib/vite_rails/manifest.rb +20 -15
  18. data/lib/vite_rails/runner.rb +2 -5
  19. data/lib/vite_rails/version.rb +1 -1
  20. data/package.json +8 -20
  21. data/package/default.vite.json +1 -1
  22. data/test/builder_test.rb +27 -22
  23. data/test/commands_test.rb +67 -0
  24. data/test/configuration_test.rb +88 -46
  25. data/test/dev_server_proxy_test.rb +101 -0
  26. data/test/dev_server_test.rb +0 -30
  27. data/test/engine_rake_tasks_test.rb +55 -17
  28. data/test/helper_test.rb +37 -105
  29. data/test/manifest_test.rb +33 -29
  30. data/test/mode_test.rb +6 -11
  31. data/test/mounted_app/test/dummy/config/vite.json +5 -11
  32. data/test/mounted_app/test/dummy/package.json +2 -1
  33. data/test/mounted_app/test/dummy/yarn.lock +208 -0
  34. data/test/rake_tasks_test.rb +5 -19
  35. data/test/runner_test.rb +31 -0
  36. data/test/test_app/app/frontend/entrypoints/application.js +2 -0
  37. data/test/test_app/config/vite.json +0 -2
  38. data/test/test_app/config/vite_additional_paths.json +5 -0
  39. data/test/test_app/config/vite_public_dir.json +5 -0
  40. data/test/test_app/public/vite-production/manifest.json +22 -0
  41. data/test/test_helper.rb +48 -14
  42. metadata +21 -23
  43. data/test/command_test.rb +0 -35
  44. data/test/dev_server_runner_test.rb +0 -83
  45. data/test/test_app/app/javascript/entrypoints/application.js +0 -10
  46. data/test/test_app/app/javascript/entrypoints/multi_entry.css +0 -4
  47. data/test/test_app/app/javascript/entrypoints/multi_entry.js +0 -4
  48. data/test/test_app/config/vite_public_root.yml +0 -20
  49. data/test/test_app/public/vite/manifest.json +0 -36
  50. data/test/vite_runner_test.rb +0 -59
  51. data/test/webpacker_test.rb +0 -15
@@ -1,14 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  # Public: Allows to resolve configuration sourced from `config/vite.json` and
4
6
  # environment variables, combining them with the default options.
5
7
  class ViteRails::Config
6
8
  delegate :as_json, :inspect, to: :@config
7
9
 
8
- def initialize(config)
9
- @config = config.tap { coerce_values(config) }.freeze
10
+ def initialize(attrs)
11
+ @config = attrs.tap { |config| coerce_values(config) }.freeze
10
12
 
11
- config.each_key do |option|
13
+ # Define getters for the configuration options.
14
+ CONFIGURABLE_WITH_ENV.each do |option|
12
15
  define_singleton_method(option) { @config[option] }
13
16
  end
14
17
  end
@@ -31,15 +34,25 @@ class ViteRails::Config
31
34
  public_dir.join(public_output_dir)
32
35
  end
33
36
 
37
+ # Public: The directory where the entries are located.
38
+ def resolved_entrypoints_dir
39
+ source_code_dir.join(entrypoints_dir)
40
+ end
41
+
34
42
  private
35
43
 
36
44
  # Internal: Coerces all the configuration values, in case they were passed
37
45
  # as environment variables which are always strings.
38
46
  def coerce_values(config)
39
- coerce_booleans(config, 'auto_build', 'https')
40
- coerce_paths(config, 'assets_dir', 'build_cache_dir', 'config_path', 'public_dir', 'source_code_dir', 'public_output_dir', 'root')
47
+ config['mode'] = config['mode'].to_s
41
48
  config['port'] = config['port'].to_i
42
- config['root'] ||= Rails.root
49
+ coerce_booleans(config, 'auto_build', 'hide_build_console_output', 'https')
50
+ coerce_paths(config, 'config_path', 'public_output_dir', 'root')
51
+
52
+ # Prefix paths that are relative to the project root.
53
+ config.slice('build_cache_dir', 'public_dir', 'source_code_dir').each do |option, dir|
54
+ config[option] = config['root'].join(dir) if dir
55
+ end
43
56
  end
44
57
 
45
58
  # Internal: Coerces configuration options to boolean.
@@ -54,11 +67,13 @@ private
54
67
 
55
68
  class << self
56
69
  # Public: Returns the project configuration for Vite.
57
- def resolve_config
58
- new DEFAULT_CONFIG.merge(config_from_file).merge(config_from_env)
59
- rescue Errno::ENOENT => error
60
- warn "Check that your vite.json configuration file is available in the load path. #{ error.message }"
61
- new DEFAULT_CONFIG.merge(config_from_env)
70
+ def resolve_config(attrs = {})
71
+ attrs = attrs.transform_keys(&:to_s)
72
+ mode = (attrs['mode'] ||= config_option_from_env('mode') || Rails.env.to_s).to_s
73
+ root = Pathname.new(attrs['root'] ||= config_option_from_env('root') || Rails.root || Dir.pwd)
74
+ config_path = (attrs['config_path'] ||= config_option_from_env('config_path') || DEFAULT_CONFIG.fetch('config_path'))
75
+ file_attrs = config_from_file(root: root, mode: mode, config_path: config_path)
76
+ new DEFAULT_CONFIG.merge(file_attrs).merge(config_from_env).merge(attrs)
62
77
  end
63
78
 
64
79
  private
@@ -70,7 +85,7 @@ private
70
85
 
71
86
  # Internal: Retrieves a configuration option from environment variables.
72
87
  def config_option_from_env(name)
73
- ENV["#{ ViteRails::ENV_PREFIX }_#{ name.upcase }"]
88
+ ViteRails.env["#{ ViteRails::ENV_PREFIX }_#{ name.upcase }"]
74
89
  end
75
90
 
76
91
  # Internal: Extracts the configuration options provided as env vars.
@@ -79,20 +94,17 @@ private
79
94
  if value = config_option_from_env(key)
80
95
  env_vars[key] = value
81
96
  end
82
- end.merge(mode: vite_mode)
83
- end
84
-
85
- # Internal: The mode Vite should run on.
86
- def vite_mode
87
- config_option_from_env('mode') || Rails.env.to_s
97
+ end
88
98
  end
89
99
 
90
100
  # Internal: Loads the configuration options provided in a JSON file.
91
- def config_from_file
92
- path = config_option_from_env('config_path') || DEFAULT_CONFIG.fetch('config_path')
93
- multi_env_config = load_json(path)
101
+ def config_from_file(root:, mode:, config_path:)
102
+ multi_env_config = load_json(root.join(config_path))
94
103
  multi_env_config.fetch('all', {})
95
- .merge(multi_env_config.fetch(vite_mode, {}))
104
+ .merge(multi_env_config.fetch(mode, {}))
105
+ rescue Errno::ENOENT => error
106
+ warn "Check that your vite.json configuration file is available in the load path. #{ error.message }"
107
+ {}
96
108
  end
97
109
  end
98
110
 
@@ -100,5 +112,5 @@ private
100
112
  DEFAULT_CONFIG = load_json("#{ __dir__ }/../../package/default.vite.json").freeze
101
113
 
102
114
  # Internal: Configuration options that can be provided as env vars.
103
- CONFIGURABLE_WITH_ENV = (DEFAULT_CONFIG.keys + ['root']).freeze
115
+ CONFIGURABLE_WITH_ENV = (DEFAULT_CONFIG.keys + %w[mode root]).freeze
104
116
  end
@@ -14,18 +14,8 @@ class ViteRails::DevServerProxy < Rack::Proxy
14
14
 
15
15
  # Rack: Intercept asset requests and send them to the Vite server.
16
16
  def perform_request(env)
17
- if vite_should_handle?(env['REQUEST_URI']) && dev_server.running?
18
- env['REQUEST_URI'] = env['REQUEST_URI']
19
- .sub(vite_asset_url_prefix, '/')
20
- .sub('.ts.js', '.ts') # Patch: Rails helpers always append the extension.
21
- env['PATH_INFO'], env['QUERY_STRING'] = env['REQUEST_URI'].split('?')
22
-
23
- env['HTTP_HOST'] = env['HTTP_X_FORWARDED_HOST'] = config.host
24
- env['HTTP_X_FORWARDED_SERVER'] = config.host_with_port
25
- env['HTTP_PORT'] = env['HTTP_X_FORWARDED_PORT'] = config.port.to_s
26
- env['HTTP_X_FORWARDED_PROTO'] = env['HTTP_X_FORWARDED_SCHEME'] = config.protocol
27
- env['HTTPS'] = env['HTTP_X_FORWARDED_SSL'] = 'off' unless config.https
28
- env['SCRIPT_NAME'] = ''
17
+ if vite_should_handle?(env) && dev_server_running?
18
+ forward_to_vite_dev_server(env)
29
19
  super(env)
30
20
  else
31
21
  @app.call(env)
@@ -34,11 +24,32 @@ class ViteRails::DevServerProxy < Rack::Proxy
34
24
 
35
25
  private
36
26
 
37
- delegate :config, :dev_server, to: :@vite_rails
27
+ delegate :config, :dev_server_running?, to: :@vite_rails
38
28
 
39
- def vite_should_handle?(url)
40
- url.start_with?(vite_asset_url_prefix) || url.start_with?(VITE_DEPENDENCY_PREFIX) ||
41
- url.include?('?t=') # Direct Hot Reload
29
+ def rewrite_uri_for_vite(env)
30
+ uri = env.fetch('REQUEST_URI') { [env['PATH_INFO'], env['QUERY_STRING']].reject(&:blank?).join('?') }
31
+ .sub(vite_asset_url_prefix, '/')
32
+ .sub('.ts.js', '.ts') # Patch: Rails helpers always append the extension.
33
+ env['PATH_INFO'], env['QUERY_STRING'] = (env['REQUEST_URI'] = uri).split('?')
34
+ end
35
+
36
+ def forward_to_vite_dev_server(env)
37
+ rewrite_uri_for_vite(env)
38
+ env['HTTP_HOST'] = env['HTTP_X_FORWARDED_HOST'] = config.host
39
+ env['HTTP_X_FORWARDED_SERVER'] = config.host_with_port
40
+ env['HTTP_PORT'] = env['HTTP_X_FORWARDED_PORT'] = config.port.to_s
41
+ env['HTTP_X_FORWARDED_PROTO'] = env['HTTP_X_FORWARDED_SCHEME'] = config.protocol
42
+ env['HTTPS'] = env['HTTP_X_FORWARDED_SSL'] = 'off' unless config.https
43
+ env['SCRIPT_NAME'] = ''
44
+ end
45
+
46
+ def vite_should_handle?(env)
47
+ path, query, referer = env['PATH_INFO'], env['QUERY_STRING'], env['HTTP_REFERER']
48
+ return true if path.start_with?(vite_asset_url_prefix) # Vite asset
49
+ return true if path.start_with?(VITE_DEPENDENCY_PREFIX) # Packages and imports
50
+ return true if query&.start_with?('t=') # Hot Reload for a stylesheet
51
+ return true if query&.start_with?('import&') # Hot Reload for an imported entrypoint
52
+ return true if referer && URI.parse(referer).path.start_with?(vite_asset_url_prefix) # Entry imported from another entry.
42
53
  end
43
54
 
44
55
  def vite_asset_url_prefix
@@ -2,40 +2,68 @@
2
2
 
3
3
  # Public: Allows to render HTML tags for scripts and styles processed by Vite.
4
4
  module ViteRails::Helper
5
+ DEFAULT_VITE_SKIP_PRELOAD_TAGS = Rails::VERSION::MAJOR <= 5 && Rails::VERSION::MINOR < 2
6
+
5
7
  # Public: Returns the current Vite Rails instance.
6
8
  def current_vite_instance
7
9
  ViteRails.instance
8
10
  end
9
11
 
12
+ # Public: Renders a script tag for vite/client to enable HMR in development.
13
+ def vite_client_tag
14
+ content_tag('script', '', src: '/@vite/client', type: 'module') if ViteRails.dev_server_running?
15
+ end
16
+
10
17
  # Public: Computes the relative path for the specified given Vite asset.
11
18
  #
12
19
  # Example:
13
20
  # <%= vite_asset_path 'calendar.css' %> # => "/vite/assets/calendar-1016838bab065ae1e122.css"
14
21
  def vite_asset_path(name, **options)
15
- current_vite_instance.manifest.lookup!(name, **options)
22
+ current_vite_instance.manifest.lookup!(name, **options).fetch('file')
16
23
  end
17
24
 
18
25
  # Public: Renders a <script> tag for the specified Vite entrypoints.
19
- def vite_javascript_tag(*names, type: 'module', **options)
20
- javascript_include_tag(*sources_from_vite_manifest_entrypoints(names, type: :javascript), type: type, **options)
26
+ def vite_javascript_tag(*names,
27
+ type: 'module',
28
+ asset_type: :javascript,
29
+ skip_preload_tags: DEFAULT_VITE_SKIP_PRELOAD_TAGS,
30
+ skip_style_tags: false,
31
+ crossorigin: 'anonymous',
32
+ **options)
33
+ js_entries = names.map { |name| current_vite_instance.manifest.lookup!(name, type: asset_type) }
34
+ js_tags = javascript_include_tag(*js_entries.map { |entry| entry['file'] }, crossorigin: crossorigin, type: type, **options)
35
+
36
+ unless skip_preload_tags || ViteRails.dev_server_running?
37
+ preload_paths = js_entries.flat_map { |entry| entry['imports'] }.compact.uniq
38
+ preload_tags = preload_paths.map { |path| preload_link_tag(path, crossorigin: crossorigin) }
39
+ end
40
+
41
+ unless skip_style_tags || ViteRails.dev_server_running?
42
+ style_paths = names.map { |name|
43
+ current_vite_instance.manifest.lookup(name.delete_suffix('.js'), type: :stylesheet)&.fetch('file')
44
+ }.compact
45
+ style_tags = stylesheet_link_tag(*style_paths)
46
+ end
47
+
48
+ safe_join [js_tags, preload_tags, style_tags]
21
49
  end
22
50
 
23
51
  # Public: Renders a <script> tag for the specified Vite entrypoints.
24
52
  #
25
53
  # NOTE: Because TypeScript is not a valid target in browsers, we only specify
26
54
  # the ts file when running the Vite development server.
27
- def vite_typescript_tag(*names, type: 'module', **options)
28
- javascript_include_tag(*sources_from_vite_manifest_entrypoints(names, type: :typescript), type: type, **options)
55
+ def vite_typescript_tag(*names, **options)
56
+ vite_javascript_tag(*names, asset_type: :typescript, **options)
29
57
  end
30
58
 
31
59
  # Public: Renders a <link> tag for the specified Vite entrypoints.
32
60
  def vite_stylesheet_tag(*names, **options)
33
- stylesheet_link_tag(*sources_from_vite_manifest_entrypoints(names, type: :stylesheet), **options)
61
+ stylesheet_link_tag(*sources_from_vite_manifest(names, type: :stylesheet), **options)
34
62
  end
35
63
 
36
64
  private
37
65
 
38
- def sources_from_vite_manifest_entrypoints(names, type:)
39
- names.flat_map { |name| vite_asset_path(name, type: type) }.uniq
66
+ def sources_from_vite_manifest(names, type:)
67
+ names.map { |name| vite_asset_path(name, type: type) }
40
68
  end
41
69
  end
@@ -5,7 +5,7 @@
5
5
  #
6
6
  # Example:
7
7
  # lookup_entrypoint('calendar', type: :javascript)
8
- # => "/vite/assets/calendar-1016838bab065ae1e314.js"
8
+ # => { "file" => "/vite/assets/calendar-1016838bab065ae1e314.js", "imports" => [] }
9
9
  #
10
10
  # NOTE: Using "autoBuild": true` in `config/vite.json` file will trigger a build
11
11
  # on demand as needed, before performing any lookup.
@@ -29,8 +29,9 @@ class ViteRails::Manifest
29
29
  # Returns a relative path, or nil if the asset is not found.
30
30
  #
31
31
  # Example:
32
- # ViteRails.manifest.lookup('calendar.js') # => "/vite/assets/calendar-1016838bab065ae1e122.js"
33
- def lookup(name, type:)
32
+ # ViteRails.manifest.lookup('calendar.js')
33
+ # # { "file" => "/vite/assets/calendar-1016838bab065ae1e122.js", "imports" => [] }
34
+ def lookup(name, type: nil)
34
35
  build if should_build?
35
36
 
36
37
  find_manifest_entry(with_file_extension(name, type))
@@ -43,12 +44,7 @@ class ViteRails::Manifest
43
44
 
44
45
  private
45
46
 
46
- delegate :config, :builder, :dev_server, to: :@vite_rails
47
-
48
- # Public: Returns true if the Vite development server is running.
49
- def dev_server_running?
50
- ViteRails.run_proxy? && dev_server.running?
51
- end
47
+ delegate :config, :builder, :dev_server_running?, to: :@vite_rails
52
48
 
53
49
  # NOTE: Auto compilation is convenient when running tests, when the developer
54
50
  # won't focus on the frontend, or when running the Vite server is not desired.
@@ -59,9 +55,9 @@ private
59
55
  # Internal: Finds the specified entry in the manifest.
60
56
  def find_manifest_entry(name)
61
57
  if dev_server_running?
62
- "/#{ config.public_output_dir.join(name.to_s) }"
63
- elsif file = manifest.dig(name.to_s, 'file')
64
- "/#{ config.public_output_dir.join(file) }"
58
+ { 'file' => "/#{ config.public_output_dir.join(name.to_s) }" }
59
+ else
60
+ manifest[name.to_s]
65
61
  end
66
62
  end
67
63
 
@@ -83,7 +79,10 @@ private
83
79
  # Internal: Returns a Hash with the entries in the manifest.json.
84
80
  def load_manifest
85
81
  if config.manifest_path.exist?
86
- JSON.parse(config.manifest_path.read)
82
+ JSON.parse(config.manifest_path.read).each do |_, entry|
83
+ entry['file'] = within_public_output_dir(entry['file'])
84
+ entry['imports'] = entry['imports']&.map { |path| within_public_output_dir(path) }
85
+ end
87
86
  else
88
87
  {}
89
88
  end
@@ -93,7 +92,13 @@ private
93
92
  def with_file_extension(name, entry_type)
94
93
  return name unless File.extname(name.to_s).empty?
95
94
 
96
- "#{ name }.#{ extension_for_type(entry_type) }"
95
+ extension = extension_for_type(entry_type)
96
+ extension ? "#{ name }.#{ extension }" : name
97
+ end
98
+
99
+ # Internal: Scopes the paths in the manifest to the output folder in public.
100
+ def within_public_output_dir(path)
101
+ "/#{ config.public_output_dir.join(path) }"
97
102
  end
98
103
 
99
104
  # Internal: Allows to receive :javascript and :stylesheet as :type in helpers.
@@ -102,7 +107,7 @@ private
102
107
  when :javascript then 'js'
103
108
  when :stylesheet then 'css'
104
109
  when :typescript then dev_server_running? ? 'ts' : 'js'
105
- else entry_type.to_s
110
+ else entry_type
106
111
  end
107
112
  end
108
113
 
@@ -31,9 +31,8 @@ private
31
31
  cmd = vite_executable
32
32
  cmd.prepend('node', '--inspect-brk') if args.include?('--debug')
33
33
  cmd.prepend('node', '--trace-deprecation') if args.delete('--trace-deprecation')
34
- args.append('--mode', ENV['RAILS_ENV']) unless args.include?('--mode') || args.include?('-m')
34
+ args.append('--mode', ViteRails.mode) unless args.include?('--mode') || args.include?('-m')
35
35
  cmd += args
36
- puts cmd.join(' ')
37
36
  Dir.chdir(File.expand_path('.', Dir.pwd)) { Kernel.exec(ViteRails.env, *cmd) }
38
37
  end
39
38
 
@@ -49,8 +48,6 @@ private
49
48
 
50
49
  # Internal: Returns a path where a Vite executable should be found.
51
50
  def vite_bin_path
52
- ENV["#{ ViteRails::ENV_PREFIX }_VITE_BIN_PATH"] || `yarn bin vite`.chomp
53
- rescue StandardError
54
- "#{ `npm bin`.chomp }/vite"
51
+ ENV["#{ ViteRails::ENV_PREFIX }_VITE_BIN_PATH"] || `yarn bin vite`.chomp.presence || "#{ `npm bin`.chomp }/vite"
55
52
  end
56
53
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class ViteRails
4
- VERSION = '1.0.4'
4
+ VERSION = '1.0.9'
5
5
  end
@@ -2,27 +2,15 @@
2
2
  "name": "only-for-workflows",
3
3
  "version": "unknown",
4
4
  "scripts": {
5
- "test": "jest",
6
- "lint": "eslint package/"
5
+ "docs": "npm -C docs run docs",
6
+ "docs:build": "npm -C docs run docs:build",
7
+ "docs:search": "npm -C docs run docs:search",
8
+ "docs:lint": "npm -C docs run lint",
9
+ "lint": "npm -C package run lint",
10
+ "test": "npm -C package run test"
7
11
  },
8
12
  "dependencies": {
9
- "vite": "^2.0.0-beta.30",
10
- "vite-plugin-ruby": "1.0.0"
11
- },
12
- "devDependencies": {
13
- "@vitejs/plugin-vue": "^1.0.6",
14
- "eslint": "^7.16.0",
15
- "eslint-config-airbnb": "^18.2.0",
16
- "eslint-config-prettier": "^7.1.0",
17
- "eslint-plugin-import": "^2.22.1",
18
- "eslint-plugin-jsx-a11y": "^6.3.1",
19
- "eslint-plugin-react": "^7.21.4",
20
- "jest": "^26.5.3"
21
- },
22
- "jest": {
23
- "testRegex": "(/__tests__/.*|(\\.|/))\\.jsx?$",
24
- "roots": [
25
- "<rootDir>/package"
26
- ]
13
+ "vite": "^2.0.0-beta.34",
14
+ "vite-plugin-ruby": "^1.0.3"
27
15
  }
28
16
  }
@@ -6,7 +6,7 @@
6
6
  "configPath": "config/vite.json",
7
7
  "publicDir": "public",
8
8
  "entrypointsDir": "entrypoints",
9
- "sourceCodeDir": "app/javascript",
9
+ "sourceCodeDir": "app/frontend",
10
10
  "host": "localhost",
11
11
  "https": null,
12
12
  "port": 3036,
@@ -2,27 +2,26 @@
2
2
 
3
3
  require 'test_helper'
4
4
 
5
- class BuilderTest < Minitest::Test
6
- def remove_files_digest_path
5
+ class BuilderTest < ViteRails::Test
6
+ def setup
7
+ refresh_config
7
8
  ViteRails.builder.send(:files_digest_path).tap do |path|
8
9
  path.delete if path.exist?
9
10
  end
10
11
  end
11
12
 
12
- def setup
13
- remove_files_digest_path
13
+ def teardown
14
+ setup
14
15
  end
15
16
 
16
- def teardown
17
- remove_files_digest_path
17
+ def vite_env
18
+ ViteRails.builder.send(:vite_env)
18
19
  end
19
20
 
20
21
  def test_custom_environment_variables
21
- assert_nil ViteRails.builder.send(:vite_env)['FOO']
22
+ assert_nil vite_env['FOO']
22
23
  ViteRails.env['FOO'] = 'BAR'
23
- assert ViteRails.builder.send(:vite_env)['FOO'] == 'BAR'
24
- ensure
25
- ViteRails.env = {}
24
+ assert vite_env['FOO'] == 'BAR'
26
25
  end
27
26
 
28
27
  def test_freshness
@@ -35,21 +34,19 @@ class BuilderTest < Minitest::Test
35
34
  end
36
35
 
37
36
  def test_freshness_on_build_success
38
- status = OpenStruct.new(success?: true)
39
-
40
37
  assert ViteRails.builder.stale?
38
+ status = OpenStruct.new(success?: true)
41
39
  Open3.stub :capture3, [:sterr, :stdout, status] do
42
- ViteRails.builder.build
40
+ assert ViteRails.builder.build
43
41
  assert ViteRails.builder.fresh?
44
42
  end
45
43
  end
46
44
 
47
45
  def test_freshness_on_build_fail
48
- status = OpenStruct.new(success?: false)
49
-
50
46
  assert ViteRails.builder.stale?
47
+ status = OpenStruct.new(success?: false)
51
48
  Open3.stub :capture3, [:sterr, :stdout, status] do
52
- ViteRails.builder.build
49
+ assert !ViteRails.builder.build
53
50
  assert ViteRails.builder.fresh?
54
51
  end
55
52
  end
@@ -58,15 +55,23 @@ class BuilderTest < Minitest::Test
58
55
  assert_equal ViteRails.builder.send(:files_digest_path).basename.to_s, "last-compilation-digest-#{ ViteRails.config.mode }"
59
56
  end
60
57
 
58
+ def test_watched_files_digest
59
+ previous_digest = ViteRails.builder.send(:watched_files_digest)
60
+ refresh_config
61
+ assert_equal previous_digest, ViteRails.builder.send(:watched_files_digest)
62
+ end
63
+
61
64
  def test_external_env_variables
62
- ViteRails.env = {}
63
- assert_equal ViteRails.builder.send(:vite_env)['VITE_RUBY_MODE'], 'production'
64
- assert_equal ViteRails.builder.send(:vite_env)['VITE_RUBY_ROOT'], Rails.root.to_s
65
+ assert_equal 'production', vite_env['VITE_RUBY_MODE']
66
+ assert_equal Rails.root.to_s, vite_env['VITE_RUBY_ROOT']
65
67
 
66
68
  ENV['VITE_RUBY_MODE'] = 'foo.bar'
67
69
  ENV['VITE_RUBY_ROOT'] = '/baz'
68
-
69
- assert_equal ViteRails.builder.send(:vite_env)['VITE_RUBY_MODE'], 'foo.bar'
70
- assert_equal ViteRails.builder.send(:vite_env)['VITE_RUBY_ROOT'], '/baz'
70
+ refresh_config
71
+ assert_equal 'foo.bar', vite_env['VITE_RUBY_MODE']
72
+ assert_equal '/baz', vite_env['VITE_RUBY_ROOT']
73
+ ensure
74
+ ENV.delete('VITE_RUBY_MODE')
75
+ ENV.delete('VITE_RUBY_ROOT')
71
76
  end
72
77
  end