roda-sprockets 1.1.0.rc1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a4a70ad21f0db49bb53cea400c3e90c27e2cae1c1d791f5c6dd471ee89b27621
4
- data.tar.gz: 4bb46d275d252145e7406463d9a6fd1e6171eacc1bc59ff45d10e977de3b030e
3
+ metadata.gz: fd58a6b5449b9ba795b8a6d89873786092742e2fc5e747801c7050725a838dfd
4
+ data.tar.gz: 2fd13d4132906fb1d2bb84b614b3abcb8a25075d16764adcb1368b4fd224c199
5
5
  SHA512:
6
- metadata.gz: 26eee21ed69f840bc04a1b024bf7d4ce7347a12d917cbfcd3eada64a7b9a76288748e99889a40fe273a150c92702c2a7048c369b1445fc078d888300055458f2
7
- data.tar.gz: 839696f0f772909e113c14776eccf09a961723ca2dd2c33aa6edf252b3d3fb3ddd078a5021889ffd292bd3f92d41c0510ec710afbad1af4af2ce9a2034c0a037
6
+ metadata.gz: 68c501fc657c52cffe278758acd7fb855ffd83a90eb5a3eb1defdf39c111be43857e75be41a18123cb68a42c22058ee4d94f52fd3bd5d6689f75695251b83d18
7
+ data.tar.gz: 8835e128d39fd716d6de20e9404ff1a0ef01a5b256bc159aa090cd4e1bea8d34f8d77442ea1867fb6c8976de383f2a986e886c7700aeaaa3610bfff02a6e2336
@@ -0,0 +1,32 @@
1
+ name: rake
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ - "*-stable"
8
+ - "*/ci-check"
9
+ pull_request: {}
10
+
11
+ jobs:
12
+ rspec:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby-version: ['2.6', '2.7', '3.0']
17
+ os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
18
+
19
+ runs-on: ${{ matrix.os }}
20
+
21
+ env:
22
+ CI: 'true'
23
+
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - name: Set up Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby-version }}
30
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
31
+ - name: Run tests
32
+ run: bundle exec rake
data/.gitignore CHANGED
@@ -1,12 +1,13 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
3
+ Gemfile.lock
4
4
  /_yardoc/
5
5
  /coverage/
6
6
  /doc/
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
+ /vendor/
10
11
  *.bundle
11
12
  *.so
12
13
  *.o
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --require spec_helper
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ v2.0.0
2
+
3
+ - :debug argument now defaults to true, if RACK_ENV is development or test,
4
+ false otherwise - also false in rake tasks (#10)
5
+ - add sprockets_env class method, so you can shorten code like
6
+ `App.sprockets_options[:sprockets]` to just `App.sprockets_env` (#11)
7
+
1
8
  v1.1.0
2
9
 
3
10
  - Fix the Rack::Lint issue (#1)
data/Gemfile CHANGED
@@ -2,3 +2,16 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in roda-sprocket_assets.gemspec
4
4
  gemspec
5
+
6
+ # For rspec:
7
+ gem "rspec"
8
+ gem "opal"
9
+ gem "opal-sprockets"
10
+ gem "sassc"
11
+ gem "uglifier"
12
+ # Until janbiedermann's Windows paths patch is released, we are using git ref:
13
+ # https://github.com/rubycdp/ferrum/commit/5beca76588d1544026eb8b8ee841f305803c67e5
14
+ # Also, my patch that captures stacktraces should be merged:
15
+ # https://github.com/hmdne/ferrum/commit/fbc74b7ca7b670d29cc53a2d779470a05c60ef9d
16
+ gem "ferrum", github: "hmdne/ferrum", ref: "capture-stacktrace"
17
+ gem "puma"
data/README.md CHANGED
@@ -22,36 +22,44 @@ And then execute:
22
22
  ```ruby
23
23
  class App < Roda
24
24
  plugin :sprockets, precompile: %w(site.js site.css),
25
- public_path: 'public/assets/',
26
25
  opal: true,
27
- debug: true
28
26
  plugin :public
29
27
 
30
28
  route do |r|
31
29
  r.public
32
- r.sprockets
33
- end
30
+ r.sprockets if %w[development test].include? ENV['RACK_ENV']
31
+ end
34
32
  end
35
33
  ```
36
34
 
37
35
  ### Parameters for the plugin:
38
36
 
39
37
  * `precompile` - an array of files that you want to precompile
40
- * `prefix` (relative to the `root`, which is `app.opts[:root]` by default,
41
- but also supports absolute paths) - an array of directories where your
42
- assets are located, by default: `%w(assets vendor/assets)`.
43
- * `root` - a filesystem root directory of your app. By default, `app.opts[:root]`.
38
+ * `prefix` (relative to the `root`, which is `app.opts[:root]` by default) -
39
+ an array of directories where your assets are located, by default:
40
+ `%w(assets vendor/assets)`.
41
+ * Here, an element of the array can be an absolute path instead of relative.
42
+ * If an element ends with `/`, it will use assets directly in a given
43
+ subdirectory.
44
+ * If it doesn't end with `/` (which is by default) if will be equivalent to
45
+ `value/*`, which means, that assets will be loaded for instance from
46
+ `assets/javascripts` and `assets/stylesheets`, but not directly from `assets`.
47
+ * An element can contain glob characters.
48
+ * `root` - a filesystem root directory of your app. By default, same as
49
+ `app.opts[:root]`, that is: `Dir.pwd`.
44
50
  * `public_path` - filesystem path to a place, where precompiled assets will be
45
51
  stored, by default: `public/assets` (it should be a directory from which `:public`
46
52
  plugin takes files + `path_prefix`)
47
53
  * `path_prefix` - a Roda prefix of your assets directory. By default: `/assets`
48
54
  * `protocol` - either :http (default) or :https.
49
- * `css_compressor`, `js_compressor` - pick a compressor of your choice.
55
+ * `css_compressor`, `js_compressor` - pick a compressor of your choice (respected
56
+ only if `debug` is false)
50
57
  * `host` - for hosting your assets on a different server
51
58
  * `digest` (bool) - digest your assets for unique filenames, default: true
52
59
  * `opal` (bool) - Opal support, default: false
53
- * `debug` (bool) - debug mode, default: false
54
- * `cache` - a `Sprockets::Cache` instance
60
+ * `debug` (bool) - debug mode, default: true if RACK_ENV is development or test,
61
+ false otherwise (in rake tasks it's false too)
62
+ * `cache` - a `Sprockets::Cache` instance, default: nil (no cache)
55
63
 
56
64
  ### Templates:
57
65
 
@@ -89,15 +97,39 @@ $document.body << DOM {
89
97
  ```
90
98
 
91
99
  You will need to tell Opal to load this file. Add this in your template
92
- after everything has been loaded or somewhere else:
100
+ after everything has been loaded (after your `javascript_tag` call, it is
101
+ needed too!):
93
102
 
94
- ```html
103
+ ```erb
95
104
  <%= opal_require 'site' %>
96
105
  ```
97
106
 
98
107
  Note that it won't be needed for plain Javascript use, only Opal needs that
99
108
  line.
100
109
 
110
+ ### Caching:
111
+
112
+ To speed up page loads during development, you can enable cache. Be warned,
113
+ there are some caveats with how Sprockets cache works. This will improve your
114
+ experience, but be prepared for some rough edges.
115
+
116
+ To enable memory cache, add an argument to your plugin config:
117
+
118
+ ```ruby
119
+ cache: Sprockets::Cache::MemoryStore.new(65536)
120
+ ```
121
+
122
+ To enable filesystem cache, for it to persist across application restarts,
123
+ add an argument to your plugin config:
124
+
125
+ ```ruby
126
+ cache: Sprockets::Cache::FileStore.new("var/cache/")
127
+ ```
128
+
129
+ Remember: with filesystem cache problems may happen if you, for instance,
130
+ update your Gems. You will then have to remove the cache for it to get
131
+ repopulated.
132
+
101
133
  ### Rake precompilation tasks:
102
134
 
103
135
  In your Rakefile:
@@ -111,6 +143,27 @@ Roda::RodaPlugins::Sprockets::Task.define!(App)
111
143
 
112
144
  And launch: `rake assets:precompile` or `rake assets:clean`
113
145
 
146
+ ### Sprockets extended configuration:
147
+
148
+ You can configure your environment directly by accessing a method `sprockets_env`
149
+ (which is a `Sprockets::Environment`) on your `App` class.
150
+
151
+ For instance, to enable Brotli with [sprockets-exporters_pack](https://github.com/hansottowirtz/sprockets-exporters_pack)
152
+ you will need to either add this code inside your `App` class:
153
+
154
+ ```ruby
155
+ sprockets_env.register_exporter %w(text/css application/javascript image/svg+xml), Sprockets::ExportersPack::BrotliExporter
156
+ ```
157
+
158
+ Or at some other point:
159
+
160
+ ```ruby
161
+ App.sprockets_env.register_exporter %w(text/css application/javascript image/svg+xml), Sprockets::ExportersPack::BrotliExporter
162
+ ```
163
+
164
+ Do note, that some extensions, like for example [opal-optimizer](https://github.com/hmdne/opal-optimizer)
165
+ won't need any configuration at all beside `require "opal/optimizer/sprockets"`.
166
+
114
167
  ## Contributing
115
168
 
116
169
  1. Fork it ( https://github.com/hmdne/roda-sprockets/fork )
data/Rakefile CHANGED
@@ -1,2 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
2
3
 
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -3,13 +3,12 @@ require 'roda'
3
3
  class App < Roda
4
4
  plugin :sprockets, precompile: %w(application.js),
5
5
  prefix: %w(app/),
6
- opal: true,
7
- debug: ENV['RACK_ENV'] != 'production'
6
+ opal: true
8
7
  plugin :public
9
8
 
10
9
  route do |r|
11
10
  r.public
12
- r.sprockets
11
+ r.sprockets if %w[development test].include? ENV['RACK_ENV']
13
12
 
14
13
  r.root do
15
14
  <<~END
@@ -0,0 +1,8 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "roda-sprockets", path: "../.."
4
+ gem "opal"
5
+ gem "opal-sprockets"
6
+ gem "puma"
7
+ gem "rake"
8
+ gem "uglifier"
@@ -0,0 +1 @@
1
+ This example drops an exception. It's for a test of source maps.
@@ -0,0 +1,6 @@
1
+ require "bundler/setup"
2
+ require "roda/plugins/sprockets_task"
3
+
4
+ require_relative "app"
5
+
6
+ Roda::RodaPlugins::Sprockets::Task.define!(App)
@@ -0,0 +1,16 @@
1
+ require 'opal'
2
+
3
+ def a
4
+ b
5
+ end
6
+
7
+ def b
8
+ 2 + 2 == 5
9
+ c
10
+ end
11
+
12
+ def c
13
+ nomethoderror
14
+ end
15
+
16
+ a
@@ -0,0 +1,26 @@
1
+ require 'roda'
2
+
3
+ class App < Roda
4
+ plugin :sprockets, precompile: %w(application.js),
5
+ prefix: %w(app/),
6
+ js_compressor: :uglify,
7
+ opal: true
8
+ plugin :public
9
+
10
+ route do |r|
11
+ r.public
12
+ r.sprockets if %w[development test].include? ENV['RACK_ENV']
13
+
14
+ r.root do
15
+ <<~END
16
+ <!doctype html>
17
+ <html>
18
+ <head>
19
+ #{ javascript_tag 'application' }
20
+ #{ opal_require 'application' }
21
+ </head>
22
+ </html>
23
+ END
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ require_relative "app"
2
+
3
+ run App.app
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "roda-sprockets", path: "../.."
4
+ gem "sassc"
5
+ gem "puma"
6
+ gem "rake"
@@ -0,0 +1,6 @@
1
+ require "bundler/setup"
2
+ require "roda/plugins/sprockets_task"
3
+
4
+ require_relative "app"
5
+
6
+ Roda::RodaPlugins::Sprockets::Task.define!(App)
@@ -0,0 +1,23 @@
1
+ require 'roda'
2
+
3
+ class App < Roda
4
+ plugin :sprockets, precompile: %w(application.css)
5
+ plugin :public
6
+
7
+ route do |r|
8
+ r.public
9
+ r.sprockets if %w[development test].include? ENV['RACK_ENV']
10
+
11
+ r.root do
12
+ <<~END
13
+ <!doctype html>
14
+ <html>
15
+ <head>
16
+ #{ stylesheet_tag 'application' }
17
+ </head>
18
+ </html>
19
+ END
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,3 @@
1
+ html, body {
2
+ background-color: green;
3
+ }
@@ -0,0 +1,3 @@
1
+ require_relative "app"
2
+
3
+ run App.app
@@ -18,7 +18,7 @@ class Roda
18
18
  host: nil,
19
19
  digest: true,
20
20
  opal: false,
21
- debug: false,
21
+ debug: nil,
22
22
  cache: nil,
23
23
  }.freeze
24
24
 
@@ -28,13 +28,21 @@ class Roda
28
28
  else
29
29
  app.opts[:sprockets] = plugin_options.dup
30
30
  end
31
- options = app.opts[:sprockets].merge! plugin_options
31
+ options = app.opts[:sprockets]
32
32
  DEFAULTS.each { |k, v| options[k] = v unless options.key?(k) }
33
33
 
34
34
  if !options[:root]
35
35
  options[:root] = app.opts[:root] || Dir.pwd
36
36
  end
37
37
 
38
+ if options[:debug].nil?
39
+ if %w[development test].include? ENV['RACK_ENV']
40
+ options[:debug] = true
41
+ else
42
+ options[:debug] = false
43
+ end
44
+ end
45
+
38
46
  # opal-sprockets registers engines when required, but if we create Sprockets::Environment before
39
47
  # requiring that, they don't get registered
40
48
  require 'opal/sprockets' if options[:opal]
@@ -76,12 +84,12 @@ class Roda
76
84
 
77
85
  options[:sprockets_helpers].environment = options[:sprockets]
78
86
  options[:sprockets_helpers].digest = options[:digest]
79
- options[:sprockets_helpers].prefix = options[:path_prefix] unless options[:path_prefix].nil?
87
+ options[:sprockets_helpers].prefix = options[:path_prefix]
80
88
  options[:sprockets_helpers].debug = options[:debug]
81
89
 
82
90
  unless options[:debug]
83
91
  options[:sprockets].css_compressor = options[:css_compressor] unless options[:css_compressor].nil?
84
- options[:sprockets].js_compressor = options[:js_compressor] unless options[:js_compressor].nil?
92
+ options[:sprockets].js_compressor = options[:js_compressor] unless options[:js_compressor].nil?
85
93
 
86
94
  options[:sprockets_helpers].manifest = ::Sprockets::Manifest.new(options[:sprockets], options[:public_path])
87
95
  options[:sprockets_helpers].protocol = options[:protocol]
@@ -94,6 +102,10 @@ class Roda
94
102
  opts[:sprockets]
95
103
  end
96
104
 
105
+ def sprockets_env
106
+ sprockets_options[:sprockets]
107
+ end
108
+
97
109
  def sprockets_regexp
98
110
  %r{#{sprockets_options[:sprockets_helpers].prefix[1..-1]}/(.*)}
99
111
  end
@@ -142,7 +154,7 @@ class Roda
142
154
  # (See: https://github.com/hmdne/roda-sprockets/issues/1)
143
155
  nil
144
156
  when Array
145
- response.join("\n")
157
+ response.join
146
158
  else
147
159
  response.to_s
148
160
  end
@@ -7,6 +7,14 @@ class Roda
7
7
  module Sprockets
8
8
  class Task < Rake::SprocketsTask
9
9
  def initialize(app_klass)
10
+ if app_klass.class != Class
11
+ raise "#{app_klass} is not a Class"
12
+ elsif !app_klass.ancestors.map(&:name).include? "Roda"
13
+ raise "#{app_klass} doesn't inherit Roda"
14
+ elsif !app_klass.respond_to? :sprockets_options
15
+ raise "#{app_klass} doesn't load 'plugin :sprockets` - we can build nothing from it"
16
+ end
17
+
10
18
  @app_klass = app_klass
11
19
  super() { update_values }
12
20
  end
@@ -18,11 +26,7 @@ class Roda
18
26
  end
19
27
 
20
28
  def sprockets_options
21
- @opts ||= begin
22
- opts = @app_klass.sprockets_options.dup
23
- opts[:debug] = false
24
- opts
25
- end
29
+ @app_klass.sprockets_options
26
30
  end
27
31
 
28
32
  def define
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "roda-sprockets"
7
- spec.version = '1.1.0.rc1'
7
+ spec.version = '2.0.0'
8
8
  spec.authors = ["cj", "hmdne"]
9
9
  spec.email = ["cjlazell@gmail.com"]
10
10
  spec.summary = %q{Use sprockets to serve assets in roda.}
@@ -0,0 +1,7 @@
1
+ @mixin scss($this, $is, $scss) {
2
+ content: "#{$this} #{$is} #{$scss}"
3
+ }
4
+
5
+ body {
6
+ @include scss(This, is, SCSS);
7
+ }
@@ -0,0 +1,13 @@
1
+ <%=
2
+ mixin = "@mixin"
3
+ incl = "@include"
4
+ <<~EOF
5
+ #{mixin} scss($this, $is, $scss) {
6
+ content: "\#{$this} \#{$is} \#{$scss}"
7
+ }
8
+
9
+ body {
10
+ #{incl} scss(This, is, ERBSCSS);
11
+ }
12
+ EOF
13
+ %>
@@ -0,0 +1 @@
1
+ @import "scss_css";
@@ -0,0 +1 @@
1
+ body { content: "Simple CSS"; }
@@ -0,0 +1,4 @@
1
+ class Test
2
+ end
3
+
4
+ Test.new
@@ -0,0 +1,10 @@
1
+ <%=
2
+ classname = "TestERB"
3
+
4
+ <<~EOF
5
+ class #{classname}
6
+ end
7
+
8
+ #{classname}.new
9
+ EOF
10
+ %>
@@ -0,0 +1 @@
1
+ require "opal_js"
@@ -0,0 +1 @@
1
+ alert("Simple JS");
@@ -0,0 +1,141 @@
1
+ require "ferrum"
2
+
3
+ def sigterm(pid)
4
+ if Gem.win_platform?
5
+ system("taskkill /F /pid #{pid}")
6
+ else
7
+ Process.kill("TERM", pid)
8
+ Process.wait(pid)
9
+ end
10
+ rescue Errno::ECHILD
11
+ # Ignore
12
+ end
13
+
14
+ def free_port
15
+ $free_port ||= 19900
16
+ $free_port += 1
17
+ $free_port
18
+ end
19
+
20
+ browser_options = {
21
+ timeout: 15,
22
+ process_timeout: 20,
23
+ js_errors: true,
24
+ browser_options: {
25
+ 'no-sandbox': nil,
26
+ 'auto-open-devtools-for-tabs': nil
27
+ }
28
+ }
29
+
30
+ RSpec.describe "Example" do
31
+ Dir[__dir__+"/../examples/*"].each do |example|
32
+ example_name = File.basename(example)
33
+
34
+ example_specific = proc do |browser, debug, error|
35
+ case example_name
36
+ when "opal-doc"
37
+ browser.evaluate("typeof(Opal.Kernel.$puts)").should be == "function"
38
+ when "opal-exception"
39
+ error.should_not be_nil
40
+ functions = error.stack_trace["callFrames"].map { |i| i["functionName"] }
41
+ if debug
42
+ functions.should include "$$a"
43
+ functions.should include "$$b"
44
+ functions.should include "$$c"
45
+ else
46
+ # We minify this example, so functions should be mangled
47
+ functions.should_not include "$$a"
48
+ functions.should_not include "$$b"
49
+ functions.should_not include "$$c"
50
+ end
51
+ # Nevertheless, "Opal.modules.application" should stay unmangled.
52
+ functions.should include "Opal.modules.application"
53
+ # How can we now test that source maps work? The browser doesn't help us...
54
+ when "sass"
55
+ browser.evaluate("window.getComputedStyle(document.body).backgroundColor").should be == "rgb(0, 128, 0)"
56
+ end
57
+ end
58
+
59
+ context example_name do
60
+ it "works in development mode" do
61
+ Dir.chdir example do
62
+ Bundler.with_unbundled_env do
63
+ if ENV.key? 'CI'
64
+ # Ensure we will reuse the cached gems
65
+ system("bundle config --local path #{__dir__+"/../vendor/bundle"}")
66
+ end
67
+
68
+ system("bundle install").should be true
69
+
70
+ begin
71
+ port = free_port
72
+ pid = spawn("bundle exec rackup -p#{port}")
73
+ sleep 1
74
+
75
+ begin
76
+ browser = Ferrum::Browser.new(**browser_options)
77
+ browser.go_to("http://localhost:#{port}/")
78
+ browser.network.wait_for_idle
79
+
80
+ # Sometimes we need to wait a little bit longer for the exception to appear.
81
+ sleep 3 if example_name == "opal-exception"
82
+
83
+ instance_exec(browser, true, nil, &example_specific)
84
+ rescue Ferrum::JavaScriptError => e
85
+ instance_exec(browser, true, e, &example_specific)
86
+ ensure
87
+ browser.quit if browser
88
+ end
89
+ ensure
90
+ sigterm(pid)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ it "works in production mode" do
97
+ Dir.chdir example do
98
+ Bundler.with_unbundled_env do
99
+ if ENV.key? 'CI'
100
+ system("bundle config --local path #{__dir__+"/../vendor/bundle"}")
101
+ end
102
+
103
+ system("bundle install").should be true
104
+
105
+ system("bundle exec rake assets:clean").should be true
106
+ -> { Dir.children(example + "/public/assets") }.should raise_error Errno::ENOENT
107
+ system("bundle exec rake assets:precompile").should be true
108
+ Dir.children(example + "/public/assets").length.should be == 3
109
+
110
+ ENV['RACK_ENV'] = 'production'
111
+
112
+ begin
113
+ port = free_port
114
+ pid = spawn("bundle exec rackup -p#{port}")
115
+ sleep 1
116
+
117
+ begin
118
+ browser = Ferrum::Browser.new(**browser_options)
119
+ browser.go_to("http://localhost:#{port}/")
120
+ browser.network.wait_for_idle
121
+
122
+ instance_exec(browser, false, nil, &example_specific)
123
+ rescue Ferrum::JavaScriptError => e
124
+ instance_exec(browser, false, e, &example_specific)
125
+ ensure
126
+ browser.quit if browser
127
+ end
128
+ ensure
129
+ system("bundle exec rake assets:clean").should be true
130
+ -> { Dir.children(example + "/public/assets") }.should raise_error Errno::ENOENT
131
+
132
+ sigterm(pid)
133
+ end
134
+ ensure
135
+ ENV.delete('RACK_ENV')
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,237 @@
1
+ require "time"
2
+ require "roda/plugins/sprockets"
3
+
4
+ RSpec.shared_examples("basic checks") do
5
+ it "returns a OK result" do
6
+ req = app.req
7
+ req.should be_ok
8
+ end
9
+
10
+ it "generates the necessary tags" do
11
+ req = app.req
12
+ if debug
13
+ req.body.should include %'<script src="/assets/#{js_name}.debug.js" type="text/javascript"'
14
+ req.body.should include %'<link rel="stylesheet" type="text/css" href="/assets/#{css_name}.debug.css">'
15
+ else
16
+ req.body.should include %'<script src="/assets/#{js_name}-'
17
+ req.body.should include %'<link rel="stylesheet" type="text/css" href="/assets/#{css_name}-'
18
+ end
19
+ end
20
+
21
+ it "generates the necessary files" do
22
+ req = app.req
23
+ req_css = app.req(req.css_path)
24
+ req_js = app.req(req.js_path)
25
+
26
+ req_css.should be_ok
27
+ req_css.body.should include css_value
28
+
29
+ req_js.should be_ok
30
+ req_js.body.should include js_value
31
+ end
32
+
33
+ it "returns a not modified status if the assets haven't been modified" do
34
+ req = app.req
35
+
36
+ etag_css = app.req(req.css_path).headers["ETag"]
37
+ etag_js = app.req(req.js_path).headers["ETag"]
38
+
39
+ req_css = app.req(req.css_path, "HTTP_IF_NONE_MATCH" => etag_css)
40
+ req_js = app.req(req.js_path, "HTTP_IF_NONE_MATCH" => etag_js)
41
+
42
+ req_css.should be_not_modified
43
+ req_js.should be_not_modified
44
+ end
45
+
46
+ it "appropriately includes source maps or not" do
47
+ req = app.req
48
+ req_css = app.req(req.css_path)
49
+ req_js = app.req(req.js_path)
50
+
51
+ if debug
52
+ req_css.body.should include "/*# sourceMappingURL="
53
+ req_js.body.should include "//# sourceMappingURL="
54
+ else
55
+ req_css.body.should_not include "/*# sourceMappingURL="
56
+ req_js.body.should_not include "//# sourceMappingURL="
57
+ end
58
+ end
59
+ end
60
+
61
+ RSpec.describe Roda::RodaPlugins::Sprockets do
62
+ context "simple app" do
63
+ let(:css_name) { "simple_css" }
64
+ let(:js_name) { "simple_js" }
65
+ let(:css_value) { "Simple CSS" }
66
+ let(:js_value) { "Simple JS" }
67
+
68
+ context "in debug mode" do
69
+ simple_debug_app = Server.gen("simple_css", "simple_js", debug: true)
70
+
71
+ let(:app) { simple_debug_app }
72
+ let(:debug) { true }
73
+
74
+ include_examples "basic checks"
75
+ end
76
+
77
+ context "in production mode" do
78
+ simple_prod_app = Server.gen("simple_css", "simple_js", debug: false)
79
+
80
+ let(:app) { simple_prod_app }
81
+ let(:debug) { false }
82
+
83
+ include_examples "basic checks"
84
+ end
85
+ end
86
+
87
+ context "opal + scss app" do
88
+ let(:css_name) { "scss_css" }
89
+ let(:js_name) { "opal_js" }
90
+ let(:css_value) { "This is SCSS" }
91
+ let(:js_value) { "$$($nesting, 'Test').$new();" }
92
+
93
+ context "in debug mode" do
94
+ opalscss_debug_app = Server.gen("scss_css", "opal_js", opal: true, debug: true)
95
+
96
+ let(:app) { opalscss_debug_app }
97
+ let(:debug) { true }
98
+
99
+ include_examples "basic checks"
100
+ end
101
+
102
+ context "in production mode" do
103
+ opalscss_prod_app = Server.gen("scss_css", "opal_js", opal: true, debug: false)
104
+
105
+ let(:app) { opalscss_prod_app }
106
+ let(:debug) { false }
107
+
108
+ include_examples "basic checks"
109
+ end
110
+ end
111
+
112
+ context "opal with requires + scss with imports app" do
113
+ let(:css_name) { "scss_css_with_imports" }
114
+ let(:js_name) { "opal_js_with_requires" }
115
+ let(:css_value) { "This is SCSS" }
116
+ let(:js_value) { "$$($nesting, 'Test').$new();" }
117
+
118
+ context "in debug mode" do
119
+ opalscssreq_debug_app = Server.gen("scss_css_with_imports", "opal_js_with_requires", opal: true, debug: true)
120
+
121
+ let(:app) { opalscssreq_debug_app }
122
+ let(:debug) { true }
123
+
124
+ include_examples "basic checks"
125
+ end
126
+
127
+ context "in production mode" do
128
+ opalscssreq_prod_app = Server.gen("scss_css_with_imports", "opal_js_with_requires", opal: true, debug: false)
129
+
130
+ let(:app) { opalscssreq_prod_app }
131
+ let(:debug) { false }
132
+
133
+ include_examples "basic checks"
134
+ end
135
+ end
136
+
137
+ context "opal with erb + scss with erb app" do
138
+ let(:css_name) { "scss_css_with_erb" }
139
+ let(:js_name) { "opal_js_with_erb" }
140
+ let(:css_value) { "This is ERBSCSS" }
141
+ let(:js_value) { "$$($nesting, 'TestERB').$new();" }
142
+
143
+ context "in debug mode" do
144
+ opalscsserb_debug_app = Server.gen("scss_css_with_erb", "opal_js_with_erb", opal: true, debug: true)
145
+
146
+ let(:app) { opalscsserb_debug_app }
147
+ let(:debug) { true }
148
+
149
+ include_examples "basic checks"
150
+ end
151
+
152
+ context "in production mode" do
153
+ opalscsserb_prod_app = Server.gen("scss_css_with_erb", "opal_js_with_erb", opal: true, debug: false)
154
+
155
+ let(:app) { opalscsserb_prod_app }
156
+ let(:debug) { false }
157
+
158
+ include_examples "basic checks"
159
+ end
160
+ end
161
+
162
+ context "opal + scss app with compressor" do
163
+ let(:css_name) { "scss_css" }
164
+ let(:js_name) { "opal_js" }
165
+ let(:css_value) { "This is SCSS" }
166
+ let(:js_value) { "Test" }
167
+
168
+ context "in debug mode" do
169
+ opalscsscomp_debug_app = Server.gen("scss_css", "opal_js",
170
+ css_compressor: :sassc, js_compressor: :uglify,
171
+ opal: true, debug: true
172
+ )
173
+
174
+ let(:app) { opalscsscomp_debug_app }
175
+ let(:debug) { true }
176
+
177
+ include_examples "basic checks"
178
+
179
+ it "should run uglifier" do
180
+ req = app.req
181
+ req_js = app.req(req.js_path)
182
+
183
+ req_js.body.should include "$$($nesting, 'Test').$new();"
184
+ end
185
+ end
186
+
187
+ context "in production mode" do
188
+ opalscsscomp_prod_app = Server.gen("scss_css", "opal_js",
189
+ css_compressor: :sassc, js_compressor: :uglify,
190
+ opal: true, debug: false
191
+ )
192
+
193
+ let(:app) { opalscsscomp_prod_app }
194
+ let(:debug) { false }
195
+
196
+ include_examples "basic checks"
197
+
198
+ it "should not run uglifier" do
199
+ req = app.req
200
+ req_js = app.req(req.js_path)
201
+
202
+ req_js.body.should_not include "$$($nesting, 'Test').$new();"
203
+ end
204
+ end
205
+ end
206
+
207
+ context "opal + scss app with cache" do
208
+ let(:css_name) { "scss_css" }
209
+ let(:js_name) { "opal_js" }
210
+ let(:css_value) { "This is SCSS" }
211
+ let(:js_value) { "$$($nesting, 'Test').$new();" }
212
+
213
+ context "in debug mode" do
214
+ opalscsscache_debug_app = Server.gen("scss_css", "opal_js",
215
+ opal: true, debug: true,
216
+ cache: Sprockets::Cache::MemoryStore.new(65536)
217
+ )
218
+
219
+ let(:app) { opalscsscache_debug_app }
220
+ let(:debug) { true }
221
+
222
+ include_examples "basic checks"
223
+ end
224
+
225
+ context "in production mode" do
226
+ opalscsscache_prod_app = Server.gen("scss_css", "opal_js",
227
+ opal: true, debug: false,
228
+ cache: Sprockets::Cache::MemoryStore.new(65536)
229
+ )
230
+
231
+ let(:app) { opalscsscache_prod_app }
232
+ let(:debug) { false }
233
+
234
+ include_examples "basic checks"
235
+ end
236
+ end
237
+ end
@@ -0,0 +1,68 @@
1
+ require "roda"
2
+
3
+ class Server < Roda
4
+ class << self
5
+ def gen(css=nil, js=nil, **kwargs, &block)
6
+ Class.new Server do |c|
7
+ unless kwargs.empty?
8
+ c.plugin :sprockets, root: __dir__, **kwargs
9
+ end
10
+
11
+ if css || js
12
+ c.route do |r|
13
+ r.sprockets
14
+
15
+ r.root do
16
+ out = ""
17
+ out += stylesheet_tag(css) if css
18
+ out += javascript_tag(js) if js
19
+ out
20
+ end
21
+ end
22
+ end
23
+
24
+ yield(c) if block_given?
25
+ end
26
+ end
27
+
28
+ # Slightly adapted from https://github.com/jeremyevans/roda/blob/master/spec/spec_helper.rb
29
+ def req(path = '/', env = {})
30
+ env['PATH_INFO'] = path.dup
31
+ env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => "/", "SCRIPT_NAME" => ""}.merge(env)
32
+ Response.new(*self.call(env))
33
+ end
34
+ end
35
+
36
+ class Response
37
+ def initialize(status, headers, body)
38
+ @status, @headers, @body = status, headers, body
39
+ end
40
+
41
+ def ok?
42
+ status == 200
43
+ end
44
+
45
+ attr_reader :status, :headers
46
+
47
+ def body
48
+ @body&.join
49
+ end
50
+
51
+ def js_path
52
+ body =~ /<script src="(.*?)"/
53
+ $1
54
+ end
55
+
56
+ def css_path
57
+ body =~ /<link rel="stylesheet" type="text\/css" href="(.*?)"/
58
+ $1
59
+ end
60
+
61
+ def not_modified?
62
+ status == 304 &&
63
+ (body.nil? || body.empty?) &&
64
+ !headers.key?("Content-Length") &&
65
+ !headers.key?("Content-Type")
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,59 @@
1
+ RSpec.configure do |config|
2
+ config.expect_with :rspec do |expectations|
3
+ # This option will default to `true` in RSpec 4. It makes the `description`
4
+ # and `failure_message` of custom matchers include text for helper methods
5
+ # defined using `chain`, e.g.:
6
+ # be_bigger_than(2).and_smaller_than(4).description
7
+ # # => "be bigger than 2 and smaller than 4"
8
+ # ...rather than:
9
+ # # => "be bigger than 2"
10
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
11
+ expectations.syntax = :should
12
+ end
13
+
14
+ config.mock_with :rspec do |mocks|
15
+ # Prevents you from mocking or stubbing a method that does not exist on
16
+ # a real object. This is generally recommended, and will default to
17
+ # `true` in RSpec 4.
18
+ mocks.verify_partial_doubles = true
19
+ end
20
+
21
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
22
+ # have no way to turn it off -- the option exists only for backwards
23
+ # compatibility in RSpec 3). It causes shared context metadata to be
24
+ # inherited by the metadata hash of host groups and examples, rather than
25
+ # triggering implicit auto-inclusion in groups with matching metadata.
26
+ config.shared_context_metadata_behavior = :apply_to_host_groups
27
+
28
+ # This allows you to limit a spec run to individual examples or groups
29
+ # you care about by tagging them with `:focus` metadata. When nothing
30
+ # is tagged with `:focus`, all examples get run. RSpec also provides
31
+ # aliases for `it`, `describe`, and `context` that include `:focus`
32
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
33
+ config.filter_run_when_matching :focus
34
+
35
+ # This setting enables warnings. It's recommended, but in some cases may
36
+ # be too noisy due to issues in dependencies.
37
+ config.warnings = true
38
+
39
+ # Print the 10 slowest examples and example groups at the
40
+ # end of the spec run, to help surface which specs are running
41
+ # particularly slow.
42
+ config.profile_examples = 10
43
+
44
+ # Run specs in random order to surface order dependencies. If you find an
45
+ # order dependency and want to debug it, you can fix the order by providing
46
+ # the seed, which is printed after each run.
47
+ # --seed 1234
48
+ config.order = :random
49
+
50
+ # Seed global randomization in this process using the `--seed` CLI option.
51
+ # Setting this allows you to use `--seed` to deterministically reproduce
52
+ # test failures related to randomization by passing the same `--seed` value
53
+ # as the one that triggered the failure.
54
+ Kernel.srand config.seed
55
+ end
56
+
57
+ require "bundler/setup"
58
+
59
+ require_relative "server_helper"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roda-sprockets
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.rc1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - cj
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-08-20 00:00:00.000000000 Z
12
+ date: 2021-09-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: roda
@@ -88,23 +88,47 @@ executables: []
88
88
  extensions: []
89
89
  extra_rdoc_files: []
90
90
  files:
91
+ - ".github/workflows/rake.yml"
91
92
  - ".gitignore"
93
+ - ".rspec"
92
94
  - CHANGELOG.md
93
95
  - Gemfile
94
96
  - LICENSE.txt
95
97
  - README.md
96
98
  - Rakefile
97
99
  - examples/opal-doc/Gemfile
98
- - examples/opal-doc/Gemfile.lock
99
100
  - examples/opal-doc/README.md
100
101
  - examples/opal-doc/Rakefile
101
102
  - examples/opal-doc/app.rb
102
103
  - examples/opal-doc/app/application.rb
103
104
  - examples/opal-doc/config.ru
105
+ - examples/opal-exception/Gemfile
106
+ - examples/opal-exception/README.md
107
+ - examples/opal-exception/Rakefile
108
+ - examples/opal-exception/app.rb
109
+ - examples/opal-exception/app/application.rb
110
+ - examples/opal-exception/config.ru
111
+ - examples/sass/Gemfile
112
+ - examples/sass/Rakefile
113
+ - examples/sass/app.rb
114
+ - examples/sass/assets/css/application.scss
115
+ - examples/sass/config.ru
104
116
  - lib/roda/plugins/sprockets.rb
105
117
  - lib/roda/plugins/sprockets_task.rb
106
118
  - lib/roda/sprockets.rb
107
119
  - roda-sprockets.gemspec
120
+ - spec/assets/css/scss_css.scss
121
+ - spec/assets/css/scss_css_with_erb.scss.erb
122
+ - spec/assets/css/scss_css_with_imports.scss
123
+ - spec/assets/css/simple_css.css
124
+ - spec/assets/js/opal_js.rb
125
+ - spec/assets/js/opal_js_with_erb.rb.erb
126
+ - spec/assets/js/opal_js_with_requires.rb
127
+ - spec/assets/js/simple_js.js
128
+ - spec/examples_spec.rb
129
+ - spec/plugin_spec.rb
130
+ - spec/server_helper.rb
131
+ - spec/spec_helper.rb
108
132
  homepage: https://github.com/hmdne/roda-sprockets
109
133
  licenses:
110
134
  - MIT
@@ -120,12 +144,24 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
144
  version: '0'
121
145
  required_rubygems_version: !ruby/object:Gem::Requirement
122
146
  requirements:
123
- - - ">"
147
+ - - ">="
124
148
  - !ruby/object:Gem::Version
125
- version: 1.3.1
149
+ version: '0'
126
150
  requirements: []
127
151
  rubygems_version: 3.2.22
128
152
  signing_key:
129
153
  specification_version: 4
130
154
  summary: Use sprockets to serve assets in roda.
131
- test_files: []
155
+ test_files:
156
+ - spec/assets/css/scss_css.scss
157
+ - spec/assets/css/scss_css_with_erb.scss.erb
158
+ - spec/assets/css/scss_css_with_imports.scss
159
+ - spec/assets/css/simple_css.css
160
+ - spec/assets/js/opal_js.rb
161
+ - spec/assets/js/opal_js_with_erb.rb.erb
162
+ - spec/assets/js/opal_js_with_requires.rb
163
+ - spec/assets/js/simple_js.js
164
+ - spec/examples_spec.rb
165
+ - spec/plugin_spec.rb
166
+ - spec/server_helper.rb
167
+ - spec/spec_helper.rb
@@ -1,47 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- roda-sprockets (1.0.2)
5
- roda (~> 3)
6
- sprockets (>= 2.2)
7
- sprockets-helpers (>= 1.4.0)
8
-
9
- GEM
10
- remote: https://rubygems.org/
11
- specs:
12
- ast (2.4.2)
13
- concurrent-ruby (1.1.9)
14
- nio4r (2.5.7)
15
- opal (1.2.0)
16
- ast (>= 2.3.0)
17
- parser (~> 3.0)
18
- opal-sprockets (1.0.1)
19
- opal (>= 1.0, < 2.0)
20
- sprockets (~> 4.0)
21
- tilt (>= 1.4)
22
- parser (3.0.2.0)
23
- ast (~> 2.4.1)
24
- puma (5.4.0)
25
- nio4r (~> 2.0)
26
- rack (2.2.3)
27
- rake (13.0.6)
28
- roda (3.46.0)
29
- rack
30
- sprockets (4.0.2)
31
- concurrent-ruby (~> 1.0)
32
- rack (> 1, < 3)
33
- sprockets-helpers (1.4.0)
34
- sprockets (>= 2.2)
35
- tilt (2.0.10)
36
-
37
- PLATFORMS
38
- ruby
39
-
40
- DEPENDENCIES
41
- opal-sprockets
42
- puma
43
- rake
44
- roda-sprockets!
45
-
46
- BUNDLED WITH
47
- 2.1.4