humid 0.0.5 → 0.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a783b726d5542a0abfc94fc1918aad0212c13ac7b6db8b8efd90c5452a222b2e
4
- data.tar.gz: b9c3719ace7b00d210c992b48f9c4ee02010e81d19c30aa47e8bf6fdd9e9373b
3
+ metadata.gz: 6c4f5090d85ea4b1c4998f6c8533816a8875039f2ffe5b5785e3e571092445c6
4
+ data.tar.gz: 844410054db5d2c89fa3fc1fd3ac4d64f83605cf4a157573ebd6d172b01d0a7f
5
5
  SHA512:
6
- metadata.gz: d29027f962022c6f8d5aeaf09c11730d572a32f8936e025fc04c3490921ac51468f6567e99f29aeb090a344150fa5edce2bbe14e83c18bfe9afc62e89fb34a87
7
- data.tar.gz: 9ceb09c4bebef88f71f3b9c229c9317526a1d5cd5100dce4a270aad383334401a14baa7e108417170c5c3cad122523e9539733404d4c9a3cdf6f7bb8c2ec5dbf
6
+ metadata.gz: 574e6c64e749180f964a3d9ffe4dd91f18179408901b4b26960b2ef3c9bbe12c601e0879fc97bb60b340ed0270be627aaf0cc92d18827deda5f45dd515d952c4
7
+ data.tar.gz: b1511fc86f5655ac063bf6d927866bd00096c7ddca23e822e2cd3dbe03a97d1e4f62288f1242c9b436e67695402c2a61a59e4f096a0dc0f3dbf450ac0fbdc250
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Humid
2
- [![Build
3
- Status](https://circleci.com/gh/thoughtbot/humid.svg?style=shield)](https://circleci.com/gh/thoughtbot/humid)
4
2
 
5
- Humid is a lightweight wrapper around [mini_racer] and [webpacker] used to
6
- generate Server Side Rendered (SSR) pages from your javascript application.
7
- While it was built for React, it can work with any JS function that returns a
8
- HTML string.
3
+ ![Build Status](https://github.com/thoughtbot/humid/actions/workflows/build.yml/badge.svg?branch=main)
4
+
5
+ Humid is a lightweight wrapper around [mini_racer] used to generate Server
6
+ Side Rendered (SSR) pages from your js-bundling builds. While it was built
7
+ for React, it can work with any JS function that returns a HTML string.
9
8
 
10
9
  ## Caution
11
10
 
@@ -34,16 +33,16 @@ Add an initializer to configure
34
33
 
35
34
  ```ruby
36
35
  Humid.configure do |config|
37
- # Name of your webpacker pack file located in `app/javascript/packs/`. You
38
- # should use a separate pack from your `application.js`.
36
+ # Path to your build file located in `app/assets/builds/`. You should use a
37
+ # separate build apart from your `application.js`.
39
38
  #
40
- # Defaults to "server_rendering.js"
41
- config.server_rendering_pack = "server_rendering.js"
39
+ # Required
40
+ config.application_path = Rails.root.join('app', 'assets', 'builds', 'server_rendering.js')
42
41
 
43
- # Name of your webpacker pack source map.
42
+ # Path to your source map file
44
43
  #
45
- # Defaults to `false`
46
- config.use_source_map = true
44
+ # Optional
45
+ config.source_map_path = Rails.root.join('app', 'assets', 'builds', 'server_rendering.js.map')
47
46
 
48
47
  # Raise errors if JS rendering failed. If false, the error will be
49
48
  # logged out to Rails log and Humid.render will return an empty string
@@ -55,8 +54,8 @@ Humid.configure do |config|
55
54
  # `console.log` and friends (`warn`, `error`) are delegated to
56
55
  # the respective logger levels on the ruby side.
57
56
  #
58
- # Defaults to `Logger.new(STDOUT)`
59
- config.logger = Rails.logger
57
+ # Defaults to `nil`
58
+ config.logger = Rails.env.development? ? Rails.logger : nil
60
59
 
61
60
  # Options passed to mini_racer.
62
61
  #
@@ -67,19 +66,32 @@ Humid.configure do |config|
67
66
  }
68
67
  end
69
68
 
70
- # Common development options
71
- if Rails.env.development? || Rails.env.test?
69
+ # Capybara defines its own puma config which is set up to run a single puma process
70
+ # with a thread pool. This ensures that a context gets created on that process.
71
+ if Rails.env.test?
72
72
  # Use single_threaded mode for Spring and other forked envs.
73
73
  MiniRacer::Platform.set_flags! :single_threaded
74
+ Humid.create_context
75
+ end
76
+ ```
74
77
 
75
- # If you're using Puma in single mode:
78
+ Then add to your `config/puma.rb`
79
+
80
+ ```
81
+ workers ENV.fetch("WEB_CONCURRENCY") { 1 }
82
+
83
+ on_worker_boot do
76
84
  Humid.create_context
77
85
  end
86
+
87
+ on_worker_shutdown do
88
+ Humid.dispose
89
+ end
78
90
  ```
79
91
 
80
92
  If you'd like support for source map support, you will need to
81
- 1. Ensure `config.use_source_map` is set to `true`
82
- 2. Add the following to your `server_rendering.js` pack.
93
+ 1. Add the following to your entry file, e.g, `server_rendering.js`.
94
+ 2. set `config.source_map_path`.
83
95
 
84
96
  ```javascript
85
97
  require("source-map-support").install({
@@ -91,6 +103,7 @@ require("source-map-support").install({
91
103
  }
92
104
  });
93
105
  ```
106
+ A [sample] webpack.config is available for reference.
94
107
 
95
108
  ## The mini_racer environment.
96
109
 
@@ -112,7 +125,8 @@ respective methods on the configured logger.
112
125
 
113
126
  ## Usage
114
127
 
115
- Pass your HTML render function to `setHumidRenderer`
128
+ In your entry file, e.g, `server_rendering.js`, pass your HTML render function
129
+ to `setHumidRenderer`. There is no need to require the function.
116
130
 
117
131
  ```javascript
118
132
  // Set a factory function that will create a new instance of our app
@@ -129,7 +143,7 @@ setHumidRenderer((json) => {
129
143
  And finally call `render` from ERB.
130
144
 
131
145
  ```ruby
132
- <%= Humid.render(initial_state) %>
146
+ <%= Humid.render(initial_state).html_safe %>
133
147
  ```
134
148
 
135
149
  Instrumentation is included:
@@ -141,7 +155,8 @@ Completed 200 OK in 14ms (Views: 0.2ms | Humid SSR: 11.0ms | ActiveRecord: 2.7ms
141
155
  ### Puma
142
156
 
143
157
  `mini_racer` is thread safe, but not fork safe. To use with web servers that
144
- employ forking, use `Humid.create_context` only on forked processes.
158
+ employ forking, use `Humid.create_context` only on forked processes. On
159
+ production, There should be no context created on the master process.
145
160
 
146
161
  ```ruby
147
162
  # Puma
@@ -156,41 +171,20 @@ end
156
171
 
157
172
  ### Server-side libraries that detect node.js envs.
158
173
  You may need webpacker to create aliases for server friendly libraries that can
159
- not detect the `mini_racer` environment.
174
+ not detect the `mini_racer` environment. For example, in `webpack.config.js`.
160
175
 
161
176
  ```diff
162
- // config/webpack/production.js
163
- // config/webpack/development.js
164
- // config/webpack/test.js
165
-
166
- process.env.NODE_ENV = process.env.NODE_ENV || 'development'
167
-
168
- const environment = require('./environment')
169
- +const path = require('path')
170
- +const ConfigObject = require('@rails/webpacker/package/config_types/config
171
-
172
- -module.exports = environment.toWebpackConfig()
173
- +const webConfig = environment.toWebpackConfig()
174
- +const ssrConfig = new ConfigObject(webConfig.toObject())
175
- +
176
- +ssrConfig.delete('entry')
177
- +ssrConfig.merge({
178
- + entry: {
179
- + server_rendering: webConfig.entry.server_rendering
180
- + },
181
- + resolve: {
182
- + alias: {
183
- + 'html-dom-parser': path.resolve(__dirname, '../../node_modules/html-dom-parser/lib/html-to-dom-server')
184
- + }
185
- + }
186
- +})
187
- +
188
- +delete webConfig.entry.server_rendering
189
- +module.exports = [ssrConfig, webConfig]
177
+ ...
178
+ resolve: {
179
+ alias: {
180
+ 'html-dom-parser': path.resolve(__dirname, '../../node_modules/html-dom-parser/lib/html-to-dom-server')
181
+ }
182
+ }
183
+ ...
190
184
  ```
191
185
 
192
186
  ## Writing universal code
193
- [Vue has an amazing resource][vue_ssr] on how to write universal code. Below
187
+ [Vue has a resource][vue_ssr] on how to write universal code. Below
194
188
  are a few highlights that are important to keep in mind.
195
189
 
196
190
  ### State
@@ -202,19 +196,17 @@ every call.
202
196
  This provides better isolation, but as it is still a shared context, polluting
203
197
  `global` is still possible. Be careful of modifying `global` in your code.
204
198
 
205
- ### Polyfills
199
+ ### Missing browser APIs
206
200
 
207
- Polyfills will fail when using in the `mini_racer` environment because of missing
208
- browser APIs. Account for this by moving the `require` to `componentDidMount`
209
- in your component.
201
+ Polyfills and some libraries that depend on browser APIs will fail in the
202
+ `mini_racer` environment because of missing browser APIs. Account for this by
203
+ moving the `require` to `useEffect` in your component.
210
204
 
211
205
  ```
212
- componentDidMount() {
213
- const dialogPolyfill = require('dialog-polyfill').default
214
- dialogPolyfill.registerDialog(this.dialog.current)
215
- this.dialog.current.open = this.props.open
216
- this.dialog.current.showModal()
217
- }
206
+ useEffect(() => {
207
+ const svgPanZoom = require('svg-pan-zoom')
208
+ //...
209
+ }, [])
218
210
  ```
219
211
 
220
212
  ## Contributing
@@ -223,23 +215,28 @@ Please see [CONTRIBUTING.md](/CONTRIBUTING.md).
223
215
 
224
216
  ## License
225
217
 
226
- Humid is Copyright © 2021-2021 Johny Ho.
218
+ Humid is Copyright © 2021-2024 Johny Ho.
227
219
  It is free software, and may be redistributed under the terms specified in the
228
220
  [LICENSE](/LICENSE.md) file.
229
221
 
222
+ <!-- START /templates/footer.md -->
230
223
  ## About thoughtbot
231
224
 
232
- ![thoughtbot](https://thoughtbot.com/brand_assets/93:44.svg)
225
+ ![thoughtbot](https://thoughtbot.com/thoughtbot-logo-for-readmes.svg)
233
226
 
234
- Humid is maintained and funded by thoughtbot, inc.
227
+ This repo is maintained and funded by thoughtbot, inc.
235
228
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
236
229
 
237
230
  We love open source software!
238
- See [our other projects][community] or
239
- [hire us][hire] to design, develop, and grow your product.
231
+ See [our other projects][community].
232
+ We are [available for hire][hire].
240
233
 
241
234
  [community]: https://thoughtbot.com/community?utm_source=github
242
- [hire]: https://thoughtbot.com?utm_source=github
235
+ [hire]: https://thoughtbot.com/hire-us?utm_source=github
236
+
237
+
238
+ <!-- END /templates/footer.md -->
239
+
243
240
  [mini_racer]: https://github.com/rubyjs/mini_racer
244
- [webpacker]: https://github.com/rails/webpacker
245
241
  [vue_ssr]: https://ssr.vuejs.org/
242
+ [sample]: ./webpack.config.js
@@ -1,4 +1,4 @@
1
- module Humid
1
+ class Humid
2
2
  module ControllerRuntime
3
3
  extend ActiveSupport::Concern
4
4
 
@@ -1,4 +1,4 @@
1
- module Humid
1
+ class Humid
2
2
  class LogSubscriber < ActiveSupport::LogSubscriber
3
3
  thread_cattr_accessor :humid_runtime
4
4
 
data/lib/humid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
- module Humid
2
- VERSION = "0.0.5".freeze
1
+ class Humid
2
+ VERSION = "0.1.0".freeze
3
3
  end
data/lib/humid.rb CHANGED
@@ -1,144 +1,109 @@
1
1
  require "mini_racer"
2
2
  require "logger"
3
- require "webpacker"
4
3
  require "active_support"
5
4
  require "active_support/core_ext"
6
5
  require "humid/log_subscriber"
7
6
  require "humid/controller_runtime"
8
7
  require "humid/version"
9
8
 
10
- module Humid
11
- extend self
12
- include ActiveSupport::Configurable
9
+ class Humid
10
+ @@context = nil
13
11
 
14
12
  class RenderError < StandardError
15
13
  end
16
14
 
17
15
  class FileNotFound < StandardError
18
16
  end
17
+
18
+ class_attribute :config
19
19
 
20
- @@context = nil
21
-
22
- config_accessor :server_rendering_pack do
23
- "server_rendering.js"
24
- end
25
-
26
- config_accessor :use_source_map do
27
- false
28
- end
29
-
30
- config_accessor :raise_render_errors do
31
- true
32
- end
33
-
34
- config_accessor :logger do
35
- Logger.new(STDOUT)
36
- end
37
-
38
- config_accessor :context_options do
39
- {}
40
- end
41
-
42
- def remove_functions
43
- <<~JS
44
- delete this.setTimeout;
45
- delete this.setInterval;
46
- delete this.clearTimeout;
47
- delete this.clearInterval;
48
- delete this.setImmediate;
49
- delete this.clearImmediate;
50
- JS
51
- end
52
-
53
- def logger
54
- config.logger
55
- end
56
-
57
- def renderer
58
- <<~JS
59
- var __renderer;
60
- function setHumidRenderer(fn) {
61
- __renderer = fn;
62
- }
63
- JS
64
- end
20
+ self.config = ActiveSupport::OrderedOptions.new.merge({
21
+ raise_render_errors: true,
22
+ context_options: {},
23
+ })
65
24
 
66
- def handle_stale_files
67
- if Webpacker.compiler.stale?
68
- Webpacker.compiler.compile
25
+ class << self
26
+ def configure
27
+ yield config
69
28
  end
70
29
 
71
- public_path = Webpacker.config.public_path
72
- server_rendering_pack = config.server_rendering_pack
73
- source_path = public_path.join(Webpacker.manifest.lookup(server_rendering_pack)[1..-1])
74
- filename = File.basename(source_path.to_s)
30
+ def remove_functions
31
+ <<~JS
32
+ delete this.setTimeout;
33
+ delete this.setInterval;
34
+ delete this.clearTimeout;
35
+ delete this.clearInterval;
36
+ delete this.setImmediate;
37
+ delete this.clearImmediate;
38
+ JS
39
+ end
75
40
 
76
- if @@current_filename != filename
77
- dispose
78
- create_context
41
+ def logger
42
+ config.logger
79
43
  end
80
- end
81
44
 
82
- def context
83
- if @@context && Webpacker.env.development?
84
- handle_stale_files
45
+ def renderer
46
+ <<~JS
47
+ var __renderer;
48
+ function setHumidRenderer(fn) {
49
+ __renderer = fn;
50
+ }
51
+ JS
85
52
  end
86
53
 
87
- @@context
88
- end
54
+ def context
55
+ @@context
56
+ end
89
57
 
90
- def dispose
91
- if @@context
92
- @@context.dispose
93
- @@context = nil
58
+ def dispose
59
+ if @@context
60
+ @@context.dispose
61
+ @@context = nil
62
+ end
94
63
  end
95
- end
96
64
 
97
- def create_context
98
- ctx = MiniRacer::Context.new(config.context_options)
99
- ctx.attach("console.log", proc { |err| logger.debug(err.to_s) })
100
- ctx.attach("console.info", proc { |err| logger.info(err.to_s) })
101
- ctx.attach("console.error", proc { |err| logger.error(err.to_s) })
102
- ctx.attach("console.warn", proc { |err| logger.warn(err.to_s) })
65
+ def create_context
66
+ ctx = MiniRacer::Context.new(**config.context_options)
103
67
 
104
- js = ""
105
- js << remove_functions
106
- js << renderer
107
- ctx.eval(js)
68
+ if logger
69
+ ctx.attach("console.log", proc { |err| logger.debug(err.to_s) })
70
+ ctx.attach("console.info", proc { |err| logger.info(err.to_s) })
71
+ ctx.attach("console.error", proc { |err| logger.error(err.to_s) })
72
+ ctx.attach("console.warn", proc { |err| logger.warn(err.to_s) })
73
+ end
108
74
 
109
- public_path = Webpacker.config.public_path
75
+ js = ""
76
+ js << remove_functions
77
+ js << renderer
78
+ ctx.eval(js)
110
79
 
111
- webpack_source_file = Webpacker.manifest.lookup(config.server_rendering_pack)
112
- if webpack_source_file.nil?
113
- raise FileNotFound.new("Humid could not find a built pack for #{config.server_rendering_pack}")
114
- end
80
+ source_path = config.application_path
81
+ map_path = config.source_map_path
115
82
 
116
- if config.use_source_map
117
- webpack_source_map = Webpacker.manifest.lookup("#{config.server_rendering_pack}.map")
118
- map_path = public_path.join(webpack_source_map[1..-1])
119
- ctx.attach("readSourceMap", proc { File.read(map_path) })
120
- end
83
+ if map_path
84
+ ctx.attach("readSourceMap", proc { File.read(map_path) })
85
+ end
121
86
 
122
- source_path = public_path.join(webpack_source_file[1..-1])
123
- filename = File.basename(source_path.to_s)
124
- @@current_filename = filename
125
- ctx.eval(File.read(source_path), filename: filename)
87
+ filename = File.basename(source_path.to_s)
88
+ @@current_filename = filename
89
+ ctx.eval(File.read(source_path), filename: filename)
126
90
 
127
- @@context = ctx
128
- end
91
+ @@context = ctx
92
+ end
129
93
 
130
- def render(*args)
131
- ActiveSupport::Notifications.instrument("render.humid") do
132
- context.call("__renderer", *args)
133
- rescue MiniRacer::RuntimeError => e
134
- message = ([e.message] + e.backtrace.filter {|x| x.starts_with? "JavaScript"}).join("\n")
135
- render_error = Humid::RenderError.new(message)
136
-
137
- if config.raise_render_errors
138
- raise render_error
139
- else
140
- config.logger.error(render_error.inspect)
141
- ""
94
+ def render(*args)
95
+ ActiveSupport::Notifications.instrument("render.humid") do
96
+ context.call("__renderer", *args)
97
+ rescue MiniRacer::RuntimeError => e
98
+ message = ([e.message] + e.backtrace.filter { |x| x.starts_with? "JavaScript" }).join("\n")
99
+ render_error = Humid::RenderError.new(message)
100
+
101
+ if config.raise_render_errors
102
+ raise render_error
103
+ else
104
+ config.logger.error(render_error.inspect)
105
+ ""
106
+ end
142
107
  end
143
108
  end
144
109
  end
metadata CHANGED
@@ -1,29 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: humid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johny Ho
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-07-31 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: webpacker
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '4.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '4.0'
27
12
  - !ruby/object:Gem::Dependency
28
13
  name: mini_racer
29
14
  requirement: !ruby/object:Gem::Requirement
@@ -41,73 +26,17 @@ dependencies:
41
26
  - !ruby/object:Gem::Dependency
42
27
  name: activesupport
43
28
  requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '6.0'
48
- type: :runtime
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '6.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '12.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
29
  requirements:
66
30
  - - "~>"
67
31
  - !ruby/object:Gem::Version
68
- version: '12.0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '3.8'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '3.8'
83
- - !ruby/object:Gem::Dependency
84
- name: byebug
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '9.0'
90
- type: :development
32
+ version: '8.0'
33
+ type: :runtime
91
34
  prerelease: false
92
35
  version_requirements: !ruby/object:Gem::Requirement
93
36
  requirements:
94
37
  - - "~>"
95
38
  - !ruby/object:Gem::Version
96
- version: '9.0'
97
- - !ruby/object:Gem::Dependency
98
- name: rails
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '6.0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '6.0'
39
+ version: '8.0'
111
40
  description: Javascript SSR rendering for Rails
112
41
  email: jho406@gmail.com
113
42
  executables: []
@@ -119,14 +48,10 @@ files:
119
48
  - lib/humid/controller_runtime.rb
120
49
  - lib/humid/log_subscriber.rb
121
50
  - lib/humid/version.rb
122
- - spec/controller_runtime_spec.rb
123
- - spec/log_subscriber_spec.rb
124
- - spec/render_spec.rb
125
51
  homepage: https://github.com/thoughtbot/humid/
126
52
  licenses:
127
53
  - MIT
128
54
  metadata: {}
129
- post_install_message:
130
55
  rdoc_options: []
131
56
  require_paths:
132
57
  - lib
@@ -141,11 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
66
  - !ruby/object:Gem::Version
142
67
  version: '0'
143
68
  requirements: []
144
- rubygems_version: 3.1.2
145
- signing_key:
69
+ rubygems_version: 3.6.9
146
70
  specification_version: 4
147
71
  summary: Javascript SSR rendering for Rails
148
- test_files:
149
- - spec/render_spec.rb
150
- - spec/log_subscriber_spec.rb
151
- - spec/controller_runtime_spec.rb
72
+ test_files: []
@@ -1,79 +0,0 @@
1
- require_relative "./support/helper"
2
-
3
- describe Humid::ControllerRuntime do
4
- controller_runtime = Humid::ControllerRuntime
5
-
6
- def set_metric value
7
- Humid::LogSubscriber.runtime = value
8
- end
9
-
10
- def clear_metric!
11
- Humid::LogSubscriber.reset_runtime = 0
12
- end
13
-
14
- reference_controller_class = Class.new {
15
- def process_action *_
16
- @process_action = true
17
- end
18
-
19
- def cleanup_view_runtime *_
20
- @cleanup_view_runtime.call
21
- end
22
-
23
- def append_info_to_payload *_
24
- @append_info_to_payload = true
25
- end
26
-
27
- def self.log_process_action *_
28
- @log_process_action.call
29
- end
30
- }
31
-
32
- controller_class = Class.new reference_controller_class do
33
- include controller_runtime
34
-
35
- def logger
36
- Logger.new(STDOUT)
37
- end
38
- end
39
-
40
- let(:controller) { controller_class.new }
41
-
42
- it "resets the metric before each action" do
43
- set_metric 42
44
- controller.send(:process_action, "foo")
45
- expect(Humid::LogSubscriber.runtime).to be(0)
46
- expect(controller.instance_variable_get("@process_action")).to be(true)
47
- end
48
-
49
- it "strips the metric of other sources of the runtime" do
50
- set_metric 1
51
- controller.instance_variable_set "@cleanup_view_runtime", -> {
52
- controller.instance_variable_set "@cleanup_view_runtime", true
53
- set_metric 13
54
- 42
55
- }
56
- returned = controller.send :cleanup_view_runtime
57
- expect(controller.instance_variable_get("@cleanup_view_runtime")).to be(true)
58
- expect(controller.humid_runtime).to eq(14)
59
- expect(returned).to be(29)
60
- end
61
-
62
- it "appends the metric to payload" do
63
- payload = {}
64
- set_metric 42
65
- controller.send :append_info_to_payload, payload
66
- expect(controller.instance_variable_get("@append_info_to_payload")).to be(true)
67
- expect(payload[:humid_runtime]).to eq(42)
68
- end
69
-
70
- it "adds metric to log message" do
71
- controller_class.instance_variable_set "@log_process_action", -> {
72
- controller_class.instance_variable_set "@log_process_action", true
73
- []
74
- }
75
- messages = controller_class.log_process_action humid_runtime: 42.101
76
- expect(controller_class.instance_variable_get("@log_process_action")).to be(true)
77
- expect(messages).to eq(["Humid SSR: 42.1ms"])
78
- end
79
- end
@@ -1,54 +0,0 @@
1
- require_relative "./support/helper"
2
- require "active_support/log_subscriber/test_helper"
3
- require "byebug"
4
-
5
- RSpec.describe Humid::LogSubscriber do
6
- around(:each) do |example|
7
- app_path = File.expand_path("./testapp", File.dirname(__FILE__))
8
- Dir.chdir(app_path) do
9
- example.run
10
- end
11
- end
12
-
13
- before(:each) do
14
- Humid::LogSubscriber.reset_runtime
15
- end
16
-
17
- context ".runtime" do
18
- it "is returns the runtime from the thread local" do
19
- expect(Humid::LogSubscriber.runtime).to eql 0
20
- key = "attr_Humid::LogSubscriber_humid_runtime"
21
- Thread.current[key] = 3
22
- expect(Humid::LogSubscriber.runtime).to eql 3
23
- end
24
- end
25
-
26
- context ".runtime=" do
27
- it "sets the runtime in a thread-safe manner" do
28
- expect(Humid::LogSubscriber.runtime).to eql 0
29
- Humid::LogSubscriber.runtime = 3
30
- key = "attr_Humid::LogSubscriber_humid_runtime"
31
- expect(Thread.current[key]).to eql 3
32
- end
33
- end
34
-
35
- context ".reset_runtime" do
36
- it "resets the runtime" do
37
- Humid::LogSubscriber.runtime = 3
38
- key = "attr_Humid::LogSubscriber_humid_runtime"
39
- expect(Thread.current[key]).to eql 3
40
-
41
- Humid::LogSubscriber.reset_runtime
42
- expect(Thread.current[key]).to eql 0
43
- expect(Humid::LogSubscriber.runtime).to eql 0
44
- end
45
- end
46
-
47
- it "is attached" do
48
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
49
- Humid.create_context
50
- expect(Humid::LogSubscriber.runtime).to eql(0)
51
- Humid.render
52
- expect(Humid::LogSubscriber.runtime).to be > 0
53
- end
54
- end
data/spec/render_spec.rb DELETED
@@ -1,188 +0,0 @@
1
- require_relative "./support/helper"
2
-
3
- RSpec.describe "Humid" do
4
- around(:each) do |example|
5
- app_path = File.expand_path("./testapp", File.dirname(__FILE__))
6
- Dir.chdir(app_path) do
7
- example.run
8
- end
9
- end
10
-
11
- describe "create_context" do
12
- after(:each) do
13
- Humid.dispose
14
- end
15
-
16
- it "creates a context with initial js" do
17
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
18
- Humid.create_context
19
-
20
- expect(Humid.context).to be_kind_of(MiniRacer::Context)
21
- end
22
-
23
- context "When the file can not be found" do
24
- it "raises" do
25
- allow(Humid.config).to receive("server_rendering_pack") { "does_not_exist.js" }
26
-
27
- expect {
28
- Humid.create_context
29
- }.to raise_error(Humid::FileNotFound, "Humid could not find a built pack for does_not_exist.js")
30
- end
31
- end
32
-
33
- it "does not have timeouts, immediates, and intervals" do
34
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
35
-
36
- Humid.create_context
37
-
38
- expect {
39
- Humid.context.eval("setTimeout()")
40
- }.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setTimeout is not defined")
41
- expect {
42
- Humid.context.eval("setInterval()")
43
- }.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setInterval is not defined")
44
- expect {
45
- Humid.context.eval("clearTimeout()")
46
- }.to raise_error(MiniRacer::RuntimeError, "ReferenceError: clearTimeout is not defined")
47
- expect {
48
- Humid.context.eval("setImmediate()")
49
- }.to raise_error(MiniRacer::RuntimeError, "ReferenceError: setImmediate is not defined")
50
- expect {
51
- Humid.context.eval("clearImmediate()")
52
- }.to raise_error(MiniRacer::RuntimeError, "ReferenceError: clearImmediate is not defined")
53
- end
54
-
55
- it "proxies to Rails logger" do
56
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
57
- Humid.create_context
58
- expect(Humid.logger).to receive(:info).with("hello")
59
-
60
- Humid.context.eval("console.info('hello')")
61
- end
62
- end
63
-
64
- describe "context" do
65
- it "returns the created context" do
66
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
67
-
68
- Humid.create_context
69
-
70
- expect(Humid.context).to be_kind_of(MiniRacer::Context)
71
- end
72
-
73
- context "when the js is stale and env is NOT dev`" do
74
- it "does not recompile the JS" do
75
- allow(Webpacker).to receive_message_chain("env.development?") { false }
76
- allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
77
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
78
-
79
- Humid.create_context
80
- prev_context = Humid.context
81
- expect(prev_context).to be_kind_of(MiniRacer::Context)
82
-
83
- allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
84
-
85
- next_context = Humid.context
86
-
87
- expect(prev_context).to eql(next_context)
88
- expect(next_context).to be_kind_of(MiniRacer::Context)
89
- end
90
- end
91
-
92
- context "when the env is development" do
93
- it "compiles the JS when stale" do
94
- allow(Webpacker).to receive_message_chain("env.development?") { true }
95
- allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
96
- allow(Webpacker).to receive_message_chain("compiler.compile")
97
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
98
-
99
- Humid.create_context
100
- prev_context = Humid.context
101
- expect(prev_context).to be_kind_of(MiniRacer::Context)
102
-
103
- allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
104
- # This simulates a changing file
105
- allow(Humid.config).to receive("server_rendering_pack") { "simple_changed.js" }
106
-
107
- next_context = Humid.context
108
-
109
- expect(prev_context).to_not eql(next_context)
110
- expect(next_context).to be_kind_of(MiniRacer::Context)
111
- end
112
-
113
- it "creates a new context when webpack-devserver already handled JS staleness" do
114
- allow(Webpacker).to receive_message_chain("env.development?") { true }
115
- allow(Webpacker).to receive_message_chain("compiler.stale?") { true }
116
- allow(Webpacker).to receive_message_chain("compiler.compile")
117
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
118
-
119
- Humid.create_context
120
- prev_context = Humid.context
121
- expect(Humid.render).to eql("hello")
122
- expect(prev_context).to be_kind_of(MiniRacer::Context)
123
-
124
- allow(Webpacker).to receive_message_chain("compiler.stale?") { false }
125
- # This simulates a changing file
126
- allow(Humid.config).to receive("server_rendering_pack") { "simple_changed.js" }
127
-
128
- next_context = Humid.context
129
-
130
- expect(prev_context).to_not eql(next_context)
131
- expect(next_context).to be_kind_of(MiniRacer::Context)
132
- expect(Humid.render).to eql("hello changed")
133
- end
134
- end
135
- end
136
-
137
- describe "render" do
138
- it "returns a js output" do
139
- allow(Humid.config).to receive("server_rendering_pack") { "simple.js" }
140
- Humid.create_context
141
-
142
- expect(Humid.render).to eql("hello")
143
- end
144
-
145
- it "applys args to the func" do
146
- allow(Humid.config).to receive("server_rendering_pack") { "args.js" }
147
- Humid.create_context
148
-
149
- args = ["a", 1, 2, [], {}]
150
-
151
- expect(Humid.render(*args)).to eql({"0" => "a", "1" => 1, "2" => 2, "3" => [], "4" => {}})
152
- end
153
-
154
- it "can use source maps to see errors" do
155
- allow(Humid.config).to receive("server_rendering_pack") { "reporting.js" }
156
- allow(Humid.config).to receive("use_source_map") { true }
157
-
158
- Humid.create_context
159
-
160
- expect {
161
- Humid.render
162
- }.to raise_error { |error|
163
- expect(error).to be_a(Humid::RenderError)
164
- message = <<~MSG
165
- Error: ^^ Look! These stack traces map to the actual source code :)
166
- JavaScript at throwSomeError (/webpack:/app/javascript/packs/components/error-causing-component.js:2:1)
167
- JavaScript at ErrorCausingComponent (/webpack:/app/javascript/packs/components/error-causing-component.js:8:1)
168
- JavaScript at /webpack:/app/javascript/packs/reporting.js:18:1
169
- MSG
170
-
171
- expect(error.message).to eql message.strip
172
- }
173
- end
174
-
175
- it "siliences render errors to the log" do
176
- allow(Humid.config).to receive("server_rendering_pack") { "reporting.js" }
177
- allow(Humid.config).to receive("raise_render_errors") { false }
178
- allow(Humid.config).to receive("use_source_map") { true }
179
-
180
- Humid.create_context
181
-
182
- expect(Humid.logger).to receive(:error)
183
- output = Humid.render
184
-
185
- expect(output).to eql("")
186
- end
187
- end
188
- end