Is there a way to show the Ruby line numbers in javascript generated by Opal - source-maps

For debugging purposes I would like to see the corresponding Ruby Source position in the javascript file generated by Opal.
Is there a simple way to achive this? I tried
# config.ru
require 'bundler'
Bundler.require
run Opal::Server.new { |s|
s.append_path 'public'
s.append_path 'src'
s.debug = true
s.source_map = true
s.main = 'application'
s.index_path = 'index_opal.html'
}
this is my application file
require 'math'
require 'opal'
require 'opal-jquery'
require 'consolelogger'
require 'harpnotes'
require 'abc_to_harpnotes'
require 'opal-raphael'
require 'opal-jspdf'
require 'opal-jszip'
require 'opal-abcjs'
require 'opal-musicaljs'
require 'raphael_engine'
require 'pdf_engine'
require 'controller'
require 'harpnote_player'
require 'text_pane'
puts "now starting zupfnoter"
puts "zupfnoter
I can only see this file in the source maps, but not the ones included by 'require'
I can even set breakpints to the puts statments at the end but nowhere else.

Here's an example on how to setup a rack up that serves source maps correctly
https://github.com/opal/opal/tree/0-6-stable/examples/rack (Opal v0.6.x)
UPDATE: The problem seems to be that you're not in debug mode.
Explanation: Current sourcemaps implementation doesn't work with concatenated assets and Sprockets doesn't support sourcemaps natively so it doesn't preserve them during concatenation.
Sprockets debug mode with Opal and Rack
To enable debug mode you need to add debug = true and use an Erb index.html in Opal::Server:
# config.ru
run Opal::Server.new do |s|
s.append_path 'src'
s.source_map = true
s.main = 'application'
s.index_path = 'index.html.erb'
s.debug = true
end
then in your index.html.erb you need to use the helper instead of a hardcoded script tag:
<%# index.html.erb %>
…
<%= javascript_include_tag 'application' %>
…

Related

Inline templating does not work along with modularity?

I'm making a modular application:
main.rb
require "sinatra/namespace"
require "haml"
Dir.glob("servers/*/server.rb").each do |server|
require_relative server
end
And I want to do inline templating:
servers/some/server.rb
namespace "/some/hello" do
get "/" do
haml :index
end
end
__END__
## index
!!!
%html
hello
But I get the:
No such file or directory - views/index.haml
It works if I move the template to main.rb but then it's kinda not modular anymore.
Had the same error in another case:
main.rb
require_relative "server_common"
get / do
haml :index
end
__END__
## index
!!!
.....
server_common.rb
require "sinatra"
.....
Solution:
require "sinatra"
set :inline_templates, caller.first[/[^:]+/]
Also had to add this because Sinatra didn't autorun.
set :app_file, caller.first[/[^:]+/]

How do you open StringIO in Ruby?

I have a Sinatra application with the following main.rb:
require 'bundler'
Bundler.require
get '/' do
##p = Pry.new
haml :index
end
post '/' do
code = params[:code]
$stdout = StringIO.new
##p.eval(code)
output = $stdout.string
$stdout = STDOUT
output_arr = []
output.each_line('\n') { |line| output_arr << line }
output_arr[1]
binding.pry
end
When I hit the binding.pry at the bottom to see if output contains any output, it seems like the IO stream is not closed, as I can't get anything to show up in the console.
However if I try to call open on StringIO.new, I receive an NoMethodError - private method 'open' called.
I am requiring 'stringio' in a config.ru file, and I've also tried requiring it in the main.rb file:
config.ru:
require 'stringio'
require './main'
run Sinatra::Application
I'm not sure if this is related but something interesting that I've noticed is that, in irb, if I require 'pry' before requiring stringio, then it returns false, otherwise it returns true.
This makes me wonder if Sinatra is including Pry from my Gemfile before loading the config.ru. Could that be the problem? Not sure how to solve this.

Extending Middleman to handle a new filetype (.JADE)

I'd like to add .jade support to Middleman. I don't need to use any of jade's dynamic features, but I'd like to compile my app in middleman rather than with my own messy compile script.
What is the simplest way to add a new file type to Middleman?
Middleman's templating is built on Tilt, so using the tilt-jade gem it should be pretty straightforward.
Here's some code for adding Mustache templates to Middleman:
require 'tilt-mustache'
# Mustache Renderer
module Middleman::Renderers::Mustache
class << self
def registered(app)
# Mustache is not included in the default gems,
# but we'll support it if available.
begin
# Require Gem
require "mustache"
# After config, setup mustache partial paths
app.after_configuration do
Mustache.template_path = source_dir
# Convert data object into a hash for mustache
provides_metadata %r{\.mustache$} do |path|
{ :locals => { :data => data.to_h } }
end
end
rescue LoadError
end
end
alias :included :registered
end
end
Middleman::Base.register Middleman::Renderers::Mustache
that should be quite easy to adapt to work with Jade.

Sinatra + Rspec2 - Use Sessions/Helpers?

I am trying to test my Sinatra app using Rspec2 but I can't get access to sessions or helper methods in my tests.
spec_helper:
require File.dirname(__FILE__) + "/../myapp.rb"
require 'rubygems'
require 'sinatra'
require 'rack/test'
require 'rspec'
require 'factory_girl'
set :environment, :test
RSpec.configure do |conf|
conf.include Rack::Test::Methods
end
def app
Sinatra::Application
end
app_spec.rb:
require File.dirname(__FILE__) + "/../spec_helper.rb"
describe 'Something' do
it "should do something" do
session["aa"] = "Test"
end
end
This throws an error, can't find session variables. Similarly I can't use helper methods which are defined in my app.
I run my tests using rspec specs/app_spec/app_spec.rb.
What am I doing wrong?
Assuming you've got your specs and spec helper in the /spec dir, then this line should go at the top of your spec:
require_relative "./spec_helper.rb"
I also like to use File.expand_path and File.join as it's more reliable than doing it yourself, e.g.
require File.dirname(__FILE__) + "/../spec_helper.rb"
becomes
require_relative File.expand_path( File.join File.dirname(__FILE__), "/../spec_helper.rb" )
Also, I don't tend to require "sinatra", the app has that. If you're missing bits from sinatra then maybe, but I add things like this instead through rack:
ENV['RACK_ENV'] = 'test'
Finally, if your Sinatra app is using the modular style then you'll have to include it too. I do this at the top of a spec, for example:
describe "The site" do
include Rack::Test::Methods
include MyApp
let(:app) { MyApp.app }
YMMV. Let us know if any of this works.
A different test to try:
before(:all) { get "/" }
subject { last_response }
it { should be_ok }

Load error when trying to include custom module

Same app, different problem. I'm working on an app using the Dan Benjamin "Meet Sinatra" screencast as a reference. I'm trying to include a custom authentication module, which is housed in a lib folder (lib/authentication.rb). I am requiring that line at the top of my code, but when I try to load the page, it claims there is no such file to load.
Any thoughts?
Here's the top of my main Sinatra file:
require 'sinatra'
require 'rubygems'
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/entries.db")
class Entry
include DataMapper::Resource
property :id, Serial
property :first_name, String
property :last_name, String
property :email, String
property :created_at, DateTime
end
# create, upgrade, or migrate tables automatically
DataMapper.auto_upgrade!
helpers do
include Sinatra::Authorization
end
And the actual Module:
module Sinatra
module Authorization
def auth
#auth ||= Rack::Auth::Basic::Request.new(request.env)
end
def unauthorized!(realm="Short URL Generator")
headers 'WWW-Authenticate' => %(Basic realm="#{realm}")
throw :halt, [ 401, 'Authorization Required' ]
end
def bad_request!
throw :halt, [ 400, 'Bad Request' ]
end
def authorized?
request.env['REMOTE_USER']
end
def authorize(username, password)
if (username=='topfunky' && password=='peepcode') then
true
else
false
end
end
def require_admin
return if authorized?
unauthorized! unless auth.provided?
bad_request! unless auth.basic?
unauthorized! unless authorize(*auth.credentials)
request.env['REMOTE_USER'] = auth.username
end
def admin?
authorized?
end
end
end
Then, on any of the handlers I want to protect, I put "require_admin."
Assuming you're using Ruby 1.9, the default $LOAD_PATH no longer includes the current directory. So while statements like require 'sinatra' work just fine (because those gems are in $LOAD_PATH), Ruby doesn't know that your lib/authorization file is located relative to your main Sinatra file.
You can add the Sinatra file's directory to the load path, and then your require statements should work fine:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
Personnaly, I use a "relative" path since I work with Ruby 1.9.2 :
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require './lib/authorization'
But I never check what would happen if my code should work on Ruby 1.8.6 again.

Resources