vite_rails 1.0.4 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
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