I am trying to call a helper method in my Sinatra application from irb in order to test its output. I know I can get a console using this tip, and I've tried racksh as well. But if I do a "defined? my_helper" I always get nil. There must be some simple way of getting at those helpers. I have a feeling that this means digging through the architecture of Rack a little bit. Any hints?
You can of course test your Sinatra helpers via IRB.
Suppose you had a modular Sinatra app with a helper method foo that printed "baz":
require "my-app.rb"
MyApp.new.helpers.foo # => "baz"
I am trying to call a helper method in my Sinatra application from irb in order to test its output
Instead of testing it over the command line, use RSpec. See How can I test helpers blocks in Sinatra, using Rspec?
Related
I have a very simple Sinatra application:
require 'sinatra'
get '/' do
settings.inspect
end
And when I go to the root path I get: Sinatra::Application which is not at all what I expected. The application also doesn't respond well when I call the development? method (NoMethodError). I get the feeling this is because of my environment. I'm running Sinatra 1.4.4 with Ruby 1.9.3 on Windows 8. Any ideas on how to figure this out?
This is right, it’s just the way Sinatra works.
The settings instance method calls the class method (with self.class.settings) and the class method simply returns self, which is Sinatra::Application in the case of classic apps, and whatever your app class is in the case of modular apps.
When you add a setting in Sinatra with set, a new method is created on the app class for it, rather than there being a separate settings object. There is no way, as far as I know, to iterate over just the settings of your app.
I'm relatively new to Sinatra, and I want to figure out a way to integrate RSpec with my Sinatra setup.
config.ru
require 'sinatra'
require 'mongoid'
require 'uri'
require './lib/twilio_wrapper'
Mongoid.load!("./config/mongoid.yml")
Dir["./controllers/*.rb"].each { |file| require file }
run Rack::URLMap.new(
'/' => HomeController.new,
'/users' => UsersController.new(TwilioWrapper.new)
)
With this setup, I can modularize my controllers and create single instances of helper classes (such as TwilioWrapper). However, if I want to set up RSpec, I need to point it to my application's class. However, in the situation above, because I'm using Rack::URLMap, I don't have a specific application class to point RSpec to.
How can I keep my code modular in the fashion outlined above while including RSpec for tests?
Rack does not care about controllers, it cares about apps. So HomeController and UsersController are 2 Sinatra applications "racked up" in Rack. These are not controllers, they are separate Rack apps. I do not think you want 2 applications but rather to put these 2 controllers in 2 files so you can spec them out separately and keep the code readable.
The naming convention for Sinatra is to name it something like MyApp to reflect this. Sinatra is a flat framework, but you can name your "controller" files what you want.
So in folder routes you can have 'users.rb' and 'home.rb' but both files have at the top
MyApp < Sinatra::Application
Then you can test using Rack::Test with Rspec.
If you do indeed want to test 2 apps and want the prefix using Rack::Test w Rspec you simply need to define app in your spec_helper or spec file as:
def app
run Rack::URLMap.new(
'/' => HomeController.new,
'/users' => UsersController.new(TwilioWrapper.new)
)
end
All Rack::Test does is rackup your Sinatra app into a test container.
Also please see Phrogz's excellent answer on how to lay out a Sinatra application
I am new to Ruby and have been asked to use it in our new project. We have also been asked to use Padrino (Sinatra) as backend/framework. For testing we have been asked to use Rspec. I have been hunting for tutorials for long that would guide in using Rspec for Ruby on Padrino. What I get is mostly with reference to RoR. But, I am in need of Ruby on Padrino.
Please guide me for the same with any starters/guides/references/discussions, etc.
Please correct me, if I am wrong anywhere. May be I haven't searched with the right combination of words/phrases for my issue.
I am using Ruby 1.9.3 and Padrino v.0.10.6.
Note : I have also referred the SO question, but it didn't help.
I never used Padrino, but it seems that it isn't much different from Sinatra.
I suggest reading Sinatra and RSpec resources.
You can get started with this:
How to use rspec in a Sinatra Application
Sinatra, RSpec and DataMapper: Configuring and using a database for tests
And by reading specs that were written by other people on GitHub. These are some of mine, but they are not the cleanest thing that exists.
EDIT: a short tutorial
Getting started with this framework is much quicker and easier than with Sinatra. :)
Install Padrino: gem install padrino
Create an application: padrino g project myapp -d datamapper -t rspec
The command speaks for itself. :)
Run the tests: rspec --color
No tests were found, obviously. Let's create one in spec/hello/hello_spec.rb:
require File.dirname(__FILE__) + "/../spec_helper.rb"
describe "get '/'" do
it "should display hello world" do
get '/'
last_response.body.should == "Hello world!"
end
end
Run the tests again.
They failed, because no route get '/' exists. Let's create it.
In app/controllers/hello.rb:
Myapp.controller do
get '/' do
"Hello world!"
end
end
Run the test: it passes!
Check Padrino's documentation for more information and cool features, such as the controllers generator and the admin interface.
Good luck!
Rails has an helper which converts distance of time in words using distance_of_time_in_words
What do I need to include if I am just using ruby at the irb prompt to get this function?
I tried require 'action_view' but it didn't help.
I also tried require 'active_support/core_ext' but that didn't help either.
This should work:
require 'action_view'
include ActionView::Helpers::DateHelper
Both of these need to be done for a couple of reasons. First, you need to require the library, so that its modules and methods are available to be called. This is why you need to do require 'action_view'.
Second, since distance_of_time_in_words is module, which does not stand on its own, it needs to be included in class. You can then access it by calling distance_of_time_in_words on an instance of that class.
When you are in the console, you already have an instance of the Object class running. You can verify this by calling self in the irb console. When you call include ActionView::Helpers::DateHelper, you are including those methods for any instance of the Object class. Since that is the implicit receiver of the irb console, you can then just save distance_of_time_in_words right on the console and get what you want!
Is there anything in the Sinatra / Rack world similar to Rails configuration loading scheme that loads one of the config\enviroments\*.rb files depending on Rails.env
I know I could develop one pretty easily, i was just wondering if there was something already in place.
If you're following the Rails convention of putting a file for each environment in config/environments/environment_name.rb, you can put something like this in your Sinatra app, or for Rack in your config.ru file:
Dir.glob(File.dirname(__FILE__) + "/config/environments/#{settings.environment}.rb", &method(:require))
With some minor modifications you could make it load other file locations/combinations. Sinatra's configure blocks work just as well, too.
It turns out that there is something from Sinatra, that provides a similar, though limited, functionality.
See the code:
https://github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L1120
So that you can do this:
class MyApp < Sinatra::Base
configure :development, :test do
#only executes this code when environment is equal to one of the passed arguments
# I'm pretty sure Sinatra sets this based on ENV['RACK_ENV']
end
end
There is one called Sinatra::ConfigFile, which now lives in Sinatra::Contrib http://www.sinatrarb.com/contrib/config_file.html
There's lots of useful stuff in there.
I adapted mine from monkrb.com (it's also yaml in RoR anyways)
YAML.load_file(path_of "config/settings.yml")[RACK_ENV]
e.g.
http://github.com/codepants/yasumi/blob/master/config/settings.yml