How to test creation of a Rack application using cucumber? - ruby

I am creating a Ruby command line application that will generate a Rack application. I want to test that the Rack application that is created is a valid Rack application. I have started using Aruba and Cucumber to test that the CLI creates the correct files and directory structure, but now I'm ready to run rackup and see that the application is running correctly. How can I get Cucumber and Capybara to interact with this newly created application?

Generate a root page for your rack application then have capybara visit whatever path you deem to be your root path and verify some sort of output on that page
def response
if request.path "/"
Rack::Response.new(render("index.html.erb"))
else
Rack::Response.new("Not Found", 404)
end
end
on rack startup: #startup_output = "foo"
generate some sort of output on your root page <%= #startup_output %>
capybara:
visit('/')
page.should have_content('foo')
If you need to have capybara start the app up try using a rake task inside the test:
system "rake rack:start"

Related

OCRA missing submodules of libraries if rack/grape api endpoints aren't called

I'm trying to pack my REST app into into an executable with OCRA. I have a few gems required in my script:
require 'rack'
require 'rack/server'
require 'grape'
require 'grape-entity'
require 'rubygems'
I skip starting the server with this:
if not defined?(Ocra)
Rack::Server.start options
end
When I try to run my server.exe:
Temp/../server.rb:221:in `default_middleware_by_environment':
cannot load such file -- rack/content_length (LoadError)
Which means that it doesn't detect submodules of rack that exist, but aren't used and therefore not included. If I add a require 'rack/content_length' it continues with cannot load such file -- rack/chunkedEven` and so on.
When I interrupted my server by hand before I also had to call a few api endpoints to have everything included.
I think my options are either:
Tell OCRA to include all the submodules of rack and grape, but compiling that list is a bit time consuming and would increase the file size
I already tried ocra server.rb --gem-full=rack --gem-full=grape, which get my server started, but when calling the API 'rack/mount/strexp' is missing again..
Calling the API within my script, but I couldn't figure out how to do that. I can't add a block to Rack::Server.start options and it does only continue when I interrupt the server.
Any ideas to implement either option, or is there another solution?
If we run the rack app with a rack handler (webrick / thin / else), we can shutdown the server in another thread so that ocra can finish packing (not sure how to do same thing with Rack::Server).
app = Rack::Directory.new ENV['HOME'] # a sample app
handler = Rack::Handler.pick %w/ thin webrick /
handler.run app do |server|
# handler.run yields a server object,
# which we shutdown when ocra is packing
if ocra_is_packing # replace with proper condition
Thread.new { sleep 10; server.shutdown }
end
end
You may have to do something else (access the server etc.) to have ocra pack appropriate dependencies.

Controlling a Ruby script from the web

I have a simple script written in Ruby that can start and stop an executable. I would like to have two buttons on a simple web page, start and stop, and execute the code on the machine the page is hosted from. What would be the easiest/lightest way of doing it?
I would suggest using Sinatra for such a small tasks. Let's start with Gemfile, if you're using bundler:
source 'https://rubygems.org'
gem 'sinatra'
gem 'slim'
Then just run "bundler install" or just install these gems manually. Let's write our tiny web server, create myapp.rb with following content:
require 'sinatra'
get '/' do
slim :index
end
post '/start' do
puts "Starting..."
redirect '/'
end
post '/stop' do
puts "Stopping..."
redirect '/'
end
This basically creates three handlers for paths "/", "/start", "/stop". "/" renders slim html template (we will get there soon), "/start" and "/stop" for now just print a text into STDOUT and redirects you back to "/". Let's create a folder "views" and file "views/index.slim" in it:
doctype html
html
head
title Simple Ruby web interface
body
form method="post" action="/start"
input type="submit" value="Start"
form method="post" action="/stop"
input type="submit" value="Stop"
This will be rendered into html with two forms with buttons, which will post into /start and /stop on submit. You can run it with just
ruby myapp.rb
This will start a web server on port 4567. Just go to localhost:4567 and press the buttons. Now you can just add actions you need to perform instead of puts "Starting..." and puts "Stopping..." and customize this very basic look of your webapp.

Sinatra exits without error

I'm very new to Sinatra, and I'm trying to get asset management & compiling working according to this article. Here is my main file so far:
require 'sinatra/base'
require 'sinatra/assetpack'
require 'sass'
class App < Sinatra::Base
register Sinatra::AssetPack
assets do
css :application, [
'/css/main.scss'
]
css_compression :sass
end
get '/hi' do
erb "Hello World!"
end
end
but, for some reason, when I run ruby main.rb, it just exits without failure or anything. Is there a special keyword to get the application to serve files?
Using the modular style of Sinatra application, as you are doing, running ruby main.rb is going to exit without error because it is being treated as a standard ruby application and no webserver is ever created.
You have two options.
1 Add run! if app_file == $0 just before the final end statement in your example.
This will allow you to run the app with ruby main.rb
2 (This is the preferred method) Create a rackup file config.ru with the following contents.
require './main.rb'
run App
Now you can serve the application with the command rackup -p 4567 where 4567 is whatever port number you want to use.
You need to start the application
require 'sinatra/base'
require 'sinatra/assetpack'
require 'sass'
class App < Sinatra::Base
register Sinatra::AssetPack
assets do
css :application, [
'/css/main.scss'
]
css_compression :sass
end
get '/hi' do
erb "Hello World!"
end
run! if app_file == $0
end
one observation, erb should point to a template, example:
get '/hi' do
erb :home
end
should look for a file in ../views/home.erb
Also Assuming you already did gem install sinatra. I would also use the rerun gem while developing in sinatra, gem install rerun then rerun ruby app.rb. Rerun will reload your project when you make changes to your code so you won't have to restart the app when ever you make a change.

How to mount a Sinatra app in a Padrino app?

Resque/Sidekiq come with a web frontend, which is a Sinatra app.
The way to mount this in a Rails app is to add this to routes (http://railscasts.com/episodes/366-sidekiq?view=asciicast):
mount Sidekiq::Web, at: "/sidekiq"
How do i mount this in a Padrino app?
Mapping it in config.ru like other Rack apps does not work
map '/sidekiq' do
run Sidekiq::Web
end
Padrino uses Padrino.mount which expects apps to respond to dependencies and setup_application. This hack (https://gist.github.com/1718723) allows you to mount a Sinatra application inside a Padrino application
Padrino app is a rack app and in config.ru you would see
require ::File.dirname(__FILE__) + '/config/boot.rb'
run Padrino.application
You can change this to use Rack::URLMap
require ::File.dirname(__FILE__) + '/config/boot.rb'
run Rack::URLMap.new("/sidekiq" => Sidekiq::Web.new, "/app" => Padrino.application.new)
Add gem 'sidekiq' to Gemfile
bundle install
Add following lines to config/boot.rb
Padrino.before_load do
Padrino.dependency_paths << Padrino.root('app/workers/*.rb')
end
Add following lines to config/apps.rb
require 'sidekiq/web'
Padrino.mount('Sidekiq', app_class: 'Sidekiq::Web', app_root: Sidekiq::Web.root).to('/sidekiq')
Create any worker in app/workers/
Run bundle exec sidekiq -r ./config/boot.rb

Trying to Workout how-to run a Ruby (Sinatra) app on the Ebb webserver

I need to write a super fast Ruby application to process web requests on Sinatra - and want to run it on the Ebb webserver. But I cannot work out how to do this. Could someone please help me?
sinatra has a -s option to specify a handler. try running your app with -s ebb.
You need to look at Rack: http://rack.rubyforge.org/
It's pretty easy really, you have a .ru file which instructs Rack how to start your application, and in your application you have a 'call' method which is called on each request, and sends the response back to Rack.
In my_app.ru
require 'my_app'
require 'ebb'
# Rack config
use Rack::Static, urls: ['/js', '/public', '/index.html']
use Rack::ShowExceptions
# Run application
run MyApp.new
In my_app.rb
class MyApp
def call env
request = Rack::Request.new env
response = Rack::Response.new
params = request.params
response.body = "Hello World"
response['Content-Length'] = response.body.size.to_s
response.finish
end
end
Then you specify the .ru file in your sinatra config, like:
rackup: my_app.ru

Resources