Skip to content

Commit 836fc8c

Browse files
committedMar 23, 2015
Merge pull request #43 from opal/elia/wip-back-to-sprockets
Back to sprockets ✨
2 parents 7ff3de2 + e258dc0 commit 836fc8c

20 files changed

+168
-109
lines changed
 

Diff for: ‎Gemfile

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ gemspec
33

44
gem 'capybara-webkit'
55
# gem 'opal-jquery', github: 'opal/opal-jquery'
6-
# gem 'opal', github: 'opal'
6+
gem 'opal', github: 'opal', branch: 'elia/wip-back-to-sprockets'
7+
# gem 'opal', github: 'opal', branch: 'elia/source-maps-fix'
78
# gem 'opal-jquery', path: '../opal-jquery'
89
# gem 'opal', path: '../opal'
910

Diff for: ‎Rakefile

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,10 @@ Bundler::GemHelper.install_tasks
1010
# TEST
1111

1212
require 'rspec/core/rake_task'
13-
RSpec::Core::RakeTask.new :default
13+
RSpec::Core::RakeTask.new :rspec
1414

15+
16+
require File.expand_path('../test_app/config/application', __FILE__)
17+
TestApp::Application.load_tasks
18+
19+
task :default => [:rspec, 'opal:spec']

Diff for: ‎app/controllers/opal_spec_controller.rb

+15-31
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,29 @@
1+
require 'opal/rails/spec_builder'
2+
13
class OpalSpecController < ActionController::Base
2-
helper_method :spec_files
4+
helper_method :spec_files, :pattern, :clean_spec_path
35

46
def run
7+
respond_to do |format|
8+
format.html
9+
format.js { render js: builder.to_s }
10+
end
511
end
612

7-
def file
8-
spec_file = Dir["#{spec_location}/#{params[:path]}*.{rb,opal}"].first
9-
Opal.paths.concat Rails.application.config.assets.paths
10-
builder = Opal::Builder.new
11-
file = File.new spec_file
12-
builder.build_str file.read, spec_file
13-
14-
render js: builder.to_s
15-
end
1613

1714
private
1815

19-
def spec_files
20-
@spec_files ||= some_spec_files || all_spec_files
21-
end
22-
23-
def specs_param
16+
def pattern
2417
params[:pattern]
2518
end
2619

27-
def some_spec_files
28-
return if specs_param.blank?
29-
specs_param.split(':').map { |path| spec_files_for_glob(path) }.flatten
20+
def builder
21+
@builder ||= Opal::Rails::SpecBuilder.new(
22+
spec_location: Rails.application.config.opal.spec_location,
23+
sprockets: Rails.application.config.assets,
24+
pattern: pattern,
25+
)
3026
end
3127

32-
def all_spec_files
33-
spec_files_for_glob '**/*_spec{.js,}'
34-
end
35-
36-
def spec_files_for_glob glob = '**'
37-
Dir[Rails.root.join("#{spec_location}/#{glob}.{rb,opal}")].map do |path|
38-
path.split("#{spec_location}/").flatten.last.gsub(/(\.rb|\.opal)/, '')
39-
end.uniq
40-
end
41-
42-
def spec_location
43-
Rails.application.config.opal.spec_location
44-
end
28+
delegate :spec_files, :clean_spec_path, to: :builder
4529
end

Diff for: ‎app/helpers/opal_helper.rb

+11-9
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ def opal_tag(&block)
55
javascript_tag js_code
66
end
77

8-
def spec_include_tag(*sources)
9-
options = sources.extract_options!.stringify_keys
10-
path_options = options.extract!('protocol', 'extname').symbolize_keys
11-
sources.uniq.map { |source|
12-
tag_options = {
13-
"src" => "/opal_spec_files/#{source}"
14-
}.merge!(options)
15-
content_tag(:script, "", tag_options)
16-
}.join("\n").html_safe
8+
def javascript_include_tag(*sources)
9+
sources_copy = sources.dup.tap(&:extract_options!)
10+
sprockets = Rails.application.assets
11+
12+
script_tags = super
13+
14+
sources_copy.map do |source|
15+
loading_code = Opal::Processor.load_asset_code(sprockets, source)
16+
script_tags << javascript_tag(loading_code)
17+
end
18+
script_tags
1719
end
1820
end

Diff for: ‎app/views/layouts/opal_spec.html.erb

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
<head>
44
<meta charset="utf-8">
55
<title>Opal Spec Runner</title>
6-
<%= javascript_include_tag 'opal-rspec-runner' %>
7-
<%= spec_include_tag *spec_files.map { |f| "#{f}"} %>
86
<style>
97
body { font-family: sans-serif; }
108
</style>

Diff for: ‎app/views/opal_spec/run.html.erb

+9-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
<h2>Running:</h2>
1+
<% if pattern.present? %>
2+
<%= link_to 'All specs', opal_spec_path %>
3+
<% end %>
24

5+
<h2>Running:</h2>
36
<ul>
47
<% spec_files.each do |spec_file| %>
58
<li>
6-
<%= link_to spec_file, "/opal_spec?pattern=#{URI.escape(spec_file)}" %>
9+
<% spec_file = clean_spec_path(spec_file) %>
10+
<%= link_to spec_file, opal_spec_path(pattern: spec_file) %>
711
</li>
812
<% end %>
913
</ul>
14+
15+
16+
<%= javascript_include_tag opal_spec_path(pattern: pattern) %>

Diff for: ‎lib/assets/javascripts/opal-rspec-runner.js.rb

-6
This file was deleted.

Diff for: ‎lib/assets/javascripts/opal_ujs.js

-4
This file was deleted.

Diff for: ‎lib/assets/javascripts/opal_ujs.js.rb

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require 'jquery'
2+
require 'jquery_ujs'
3+
require 'opal'
4+
require 'opal-jquery'

Diff for: ‎lib/assets/javascripts/sprockets_runner.rb.erb

-11
This file was deleted.

Diff for: ‎lib/opal/rails/engine.rb

+8-6
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,16 @@ class Engine < ::Rails::Engine
3636
end
3737

3838
app.routes.prepend do
39-
if Opal::Processor.source_map_enabled
40-
prefix = app.config.assets.prefix
41-
maps_app = Opal::SourceMapServer.new(app.assets, prefix)
42-
mount Rack::Cascade.new([maps_app, app.assets]) => prefix
39+
if Opal::Processor.source_map_enabled && config.assets.compile
40+
maps_prefix = '/__OPAL_SOURCE_MAPS__'
41+
maps_app = Opal::SourceMapServer.new(app.assets, maps_prefix)
42+
43+
::Opal::Sprockets::SourceMapHeaderPatch.inject!(maps_prefix)
44+
45+
mount maps_app => maps_prefix
4346
end
4447

45-
get '/opal_spec' => 'opal_spec#run'
46-
get '/opal_spec_files/*path' => 'opal_spec#file'
48+
get '/opal_spec' => 'opal_spec#run', as: :opal_spec
4749
end
4850
end
4951

Diff for: ‎lib/opal/rails/spec_builder.rb

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module Opal
2+
module Rails
3+
class SpecBuilder
4+
def initialize(options)
5+
@root = options.fetch(:root) { ::Rails.root }
6+
@pattern = options.fetch(:pattern, nil)
7+
@sprockets = options.fetch(:sprockets)
8+
@spec_location = options.fetch(:spec_location)
9+
end
10+
11+
attr_reader :sprockets, :pattern, :spec_location, :root
12+
13+
def to_s
14+
builder.build_str main_code, 'opal_spec'
15+
builder.to_s + 'Opal.load("opal_spec");'
16+
end
17+
18+
def builder
19+
@builder ||= begin
20+
path_finder = Opal::HikePathFinder.new(paths)
21+
22+
Opal::Builder.new(
23+
compiler_options: Opal::Processor.compiler_options,
24+
stubs: Opal::Processor.stubbed_files,
25+
path_reader: Opal::PathReader.new(path_finder),
26+
)
27+
end
28+
end
29+
30+
def paths
31+
[spec_location] + Opal.paths + sprockets.paths
32+
end
33+
34+
def main_code(files = spec_files)
35+
requires(files).map { |file| "require #{file.inspect}\n" }.join + boot_code
36+
end
37+
38+
def requires(files)
39+
['opal', 'opal-rspec', *files.map{|f| clean_spec_path(f)}]
40+
end
41+
42+
def boot_code
43+
'Opal::RSpec::Runner.autorun'
44+
end
45+
46+
def spec_files
47+
@spec_files ||= some_spec_files || all_spec_files
48+
end
49+
50+
def some_spec_files
51+
return if pattern.blank?
52+
pattern.split(':').map { |path| spec_files_for_glob(path) }.flatten
53+
end
54+
55+
def all_spec_files
56+
spec_files_for_glob '**/*_spec'
57+
end
58+
59+
def spec_files_for_glob glob = '**'
60+
Dir[root.join("#{spec_location}/#{glob}{,.js}.{rb,opal}")]
61+
end
62+
63+
def clean_spec_path(path)
64+
path.split("#{spec_location}/").flatten.last.gsub(/(\.js)?\.(rb|opal)$/, '')
65+
end
66+
end
67+
end
68+
end

Diff for: ‎lib/tasks/opal-rails_tasks.rake

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
require 'opal/rspec/rake_task'
22

33
Opal::RSpec::RakeTask.new('opal:spec' => :environment) do |server|
4-
require 'tempfile'
4+
require 'opal/rails/spec_builder'
5+
pattern = ENV['PATTERN'] || nil
56

6-
asset_paths = Opal.paths + Rails.configuration.assets.paths.to_a
7-
tempfile = Tempfile.new(['opal-rspec', '.js.rb'])
7+
builder = Opal::Rails::SpecBuilder.new(
8+
spec_location: Rails.application.config.opal.spec_location,
9+
sprockets: Rails.application.config.assets,
10+
pattern: pattern,
11+
)
812

913
server.sprockets.clear_paths
10-
asset_paths << File.dirname(tempfile.path)
11-
asset_paths << Rails.application.config.opal.spec_location
12-
server.main = File.basename(tempfile.path, '.js.rb')
14+
builder.paths.each { |path| server.append_path path }
1315

14-
asset_paths.each { |path| server.append_path path }
16+
# require 'tempfile'
17+
# tempfile = Tempfile.new(['opal-rspec', '.js.rb'])
18+
# tempfile.puts builder.main_code
19+
# tempfile.close
20+
# server.main = File.basename(tempfile.path, '.js.rb')
21+
# server.append_path File.dirname(tempfile.path)
1522

16-
required_assets = ['opal']
17-
required_assets << 'opal-rspec-runner'
18-
19-
asset_paths.each do |path|
20-
Dir["#{path}/spec/**_spec.js.{opal,rb}"].each do |spec|
21-
spec = spec[path.size+1..-1] # +1 is for the trailing slash
22-
required_assets << spec
23-
end
24-
end
25-
26-
required_assets.each { |a| tempfile.puts "require #{a.inspect}" }
27-
tempfile.close
23+
spec_file = Rails.root.join('tmp/opal_spec.rb')
24+
server.append_path spec_file.dirname.to_s
25+
spec_file.open('w') { |f| f << builder.main_code }
26+
main = spec_file.basename.to_s.gsub(/\.rb$/, '')
27+
server.main = main
2828
end

Diff for: ‎opal-rails.gemspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
2424
s.add_dependency 'rails', '>= 3.2', '< 5.0'
2525
s.add_dependency 'opal', '~> 0.7.0'
2626
s.add_dependency 'opal-jquery', '~> 0.3.0'
27-
s.add_dependency 'opal-rspec', '~> 0.4.0'
27+
s.add_dependency 'opal-rspec', '~> 0.4.1'
2828
s.add_dependency 'jquery-rails'
2929
s.add_dependency 'opal-activesupport', '>= 0.0.5'
3030

Diff for: ‎spec/integration/assigns_spec.rb

+4-3
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ def get_source_of path
2626
end
2727

2828
def opal_eval source
29-
opal_source = get_source_of '/assets/opal.js'
29+
builder = Opal::Builder.new
30+
builder.build 'opal'
3031

3132
# Any lib should be already required in the page,
3233
# require won't work in this kind of templates.
33-
opal_source << get_source_of('/assets/native.js')
34+
builder.build 'native'
3435

35-
context = ExecJS.compile opal_source
36+
context = ExecJS.compile builder.to_s
3637
context.eval source
3738
rescue
3839
$!.message << "\n\n#{source}"

Diff for: ‎spec/integration/in_browser_specs_spec.rb

+8-6
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,19 @@
33
feature 'In-browser specs runner' do
44
scenario 'runs all specs', :js do
55
visit '/opal_spec'
6-
7-
page.should have_content('subdirectory/other_spec.js')
8-
page.should have_content('example_spec.js ')
9-
page.should have_content('2 examples, 0 failures')
6+
page.should have_content('example_spec ')
7+
page.should have_content('requires_opal_spec ')
8+
page.should have_content('subdirectory/other_spec ')
9+
page.should have_content('3 examples, 0 failures')
1010
end
1111

1212
scenario "runs single spec file", :js do
1313
visit '/opal_spec'
14-
click_link 'subdirectory/other_spec.js'
14+
click_link 'subdirectory/other_spec'
1515

16-
page.should have_content('Running: subdirectory/other_spec.js')
16+
page.should_not have_content('example_spec ')
17+
page.should_not have_content('requires_opal_spec ')
18+
page.should have_content('subdirectory/other_spec ')
1719
page.should have_content('1 examples, 0 failures')
1820
end
1921
end

Diff for: ‎spec/integration/source_map_spec.rb

+4-5
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@
3232

3333
def extract_map_path response
3434
source_map_regexp = %r{^//[@#] sourceMappingURL=([^\n]+)}
35-
map_path = (response.headers['X-SourceMap'] ||
36-
response.body.scan(source_map_regexp).
37-
flatten.first.to_s.strip)
38-
File.join(File.dirname(js_asset_path), map_path) if map_path
39-
end
35+
header_map_path = response.headers['X-SourceMap']
36+
comment_map_path = response.body.scan(source_map_regexp).flatten.first.to_s.strip
4037

38+
header_map_path or comment_map_path
39+
end
4140
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
require 'opal'
2+
3+
describe 'a running spec' do
4+
it 'runs successfully' do
5+
'I run'.should =~ /run/
6+
end
7+
end

Diff for: ‎test_app/config/environments/production.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
config.action_controller.perform_caching = true
1010

1111
# Disable Rails's static asset server (Apache or nginx will already do this)
12-
config.serve_static_assets = false
12+
config.serve_static_files = false
1313

1414
# Compress JavaScripts and CSS
1515
config.assets.compress = true

Diff for: ‎test_app/config/environments/test.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
config.cache_classes = true
99

1010
# Configure static asset server for tests with Cache-Control for performance
11-
config.serve_static_assets = true
11+
config.serve_static_files = true
1212
config.static_cache_control = "public, max-age=3600"
1313

1414
# Log error messages when you accidentally call methods on nil

0 commit comments

Comments
 (0)
Please sign in to comment.