Rails -- use RSpec "get" and "response" methods in Rake task - ruby

I know RSpec has useful methods "get" and "response.should" to run integration tests - I want to know how I can use these (or other methods to achieve the same result) in a Rake task:
desc "Check all content items with type 0 and do something"
task :my_task => :environment do
ContentItem.where("content_type = ?", 0).each do |obj|
get "/my_path/"+obj.value
if (response has a certain html tag)
perform some action on obj
end
end
end
I know that I can't just run rspec methods like that, but this is effectively what I need to do, and I need to be able to process information returned when /my_path/obj.value is opened. Does anyone have any suggestions?

why do you need to go through the url to do this action with your ContentItem ? Why not just use the local obj and do stuff?
Basically it looks like you're mixing up view-code with model code here... the model's object should not depend on values in the html... if there is some information being figured out in the view... put it into a method on the ContentItem model and call that code either from the view... or from this rake task.
Edit:
Ok.... well if you really need to GET a URL - look into Ruby's Net::Http gem - that will literally fetch URLs. Rails doesn't do that as standard... even for local URLs.
You might then be able to use a parser such as hpricot or nokogiri to parse the results to find the tag you need.

Related

My function works in practice but does not pass tests rspec

Perhaps it is my lack of familiarity with rspec but i do not understand what is going on with my test.
I have 2 classes one called Scrape, the other Result (creative) Scrape is a web scraping class that searches a site and scrapes the results from the page, creating a new Result instance from each.
Result instances are stored in a class variable array accessible via Result.all
this works in practice in the actual program, however when I tried to write a test for this behavior it fails.
describe "#scrape_results" do
it "accepts a url scrapes the page and creates a Result for each" do
s = Scrape.new
s.scrape_results(#url)
expect(Result.all.count).not_to eq(0)
end
end
every time i run the test Result.all.count is 0
if i use pry and manually run #scrape_results the test passes.
I appreciate your time, patience, and help
thanks
I notice that you are passing #url to #scrape_results in your test. Unless you are defining that variable inside of the describe block or the test block it will be nil in your test. It is possible that since #url might be something other than nil from wherever you are pry-ing which is causing the Result to be created and the test to pass.

Get Status from Scenario with Cucumber 2.0.0

It looks like its no longer possible use
scenario.status
in Cucumber 2.0.0 to determine the status of a scenario (passed, failed, undefined, skipped). It looks like it is possible to see if a scenario either passes or fails, but I'm also looking to see when steps are undefined or skipped.
Previously, in my code I would write the results to a DB in the After hook of the scenario, like so:
After do |scenario|
#controller.post_results(scenario)
end
Inside of post results, I would call scenario.status to get the status.
Is this no longer possible to do with Cucumber 2.0.0? If it is, what is the new method?
You need to use Hooks.rb to get the status of scenario.
You can use
if scenario.failed?
todo...
end
or
scenario.status
inside the hooks.rb.
Find more details here: https://github.com/cucumber/cucumber/wiki/Hooks

Render a view's output later via a delayed_job

If I render html I get html to the browser which works great. However, how can I get a route's response (the html) when being called in a module or class.
I need to do this because I'm sending documents to DocRaptor and rather than store the markup/html in a db column I would like to instead store record IDs and create the markup when the job executes.
A possible solution is using Ruby's HTTP library, Httparty or wget or something and open up the route and use the response.body. Before doing so I thought I'd ask around.
Thanks!
-- Update --
Here's something like what I ended up going with:
Quick tip - in case anyone does this and need their helper methods you need to extend AV with ApplicationHelper:
Here's something like what I ended up doing:
av = ActionView::Base.new()
av.view_paths = ActionController::Base.view_paths
av.extend ApplicationHelper #or any other helpers your template may need
body = av.render(:template => "orders/receipt.html.erb",:locals => {:order => order})
Link:
http://www.rigelgroupllc.com/blog/2011/09/22/render-rails3-views-outside-of-your-controllers/
check this question out, it contains the code probably want in an answer:
Rails 3 > Rendering views in rake task

Passing options and parameters to Test/Unit via Rake::TestTask

So I've been trying to figure this out, and the best solution I can came up with his global variables - but that seems so dirty and 1974 - Am I missing a feature of Rake/ Test::Unit?
I have a Rake file in which I'm running tests:
Rake::TestTask.new(:test) do |t|
t.test_files = FileList['test_*.rb']
end
and test_1.rb has something like this:
require "test/unit"
class TestStuff < Test::Unit::TestCase
def setup
#thingy = Thing.New(parameter1, parameter2)
end
def test_this_thing
#thing.do()
end
end
My problem is, Thing.new() requires arguments, and those arguments are specific to my environment. In reality, I'm running Selenium-WebDriver, and I want to pass in a browser type, and a url, etc... sometimes I want ff, othertimes I want chrome... sometimes this URL, sometimes that... depending on the day, etc.
The simplest thing seems to do something like:
#all that rake stuff
$parameter1 = x
$parameter2 = y
and then make Thing.new() look up my global vars:
#thingy = Thing.New($parameter1, $parameter2)
This seems sloppy.. and it just doesn't feel right to me. I'm still trying to get this 'test harness' up and running, and want to do it right the first time. That's why I chose Rake, based on a lot of other feedback.
Keep in mind, I'll probably have 100's of tests, ultimately, and they'll all need to do get this information... I thought Rake was good at making sure all of this was easy, but it doesn't seem to be.
Where did I go wrong?
I have used YAML files to store my configuration (browser config, environments including URLs, etc).
You can also use an environmental variable to define simple configurations. You can access environmental variables via ENV['foobar'] in Ruby.
So, for example, my browser call might look like this inside my setup method:
driver = Selenium::WebDriver.for (ENV['SWD_BROWSER'] || "firefox").to_sym
and in my Rake file (or in the shell console) define the environmental variable to use.

Partial HAML templating in Ruby without Rails

I really don’t need the overhead of Rails for my very small project, so I’m trying to achieve this just using just plain Ruby and HAML.
I want to include another HAML file inside my HAML template. But I haven’t found a good—or really usable—way of doing this.
For example, I have these two HAML files:
documents.haml
%html
%body
= include(menu.haml) body
%article …
menu.haml
%ul
%li
%a whatever …
Include is obviously not the way to go here. But it does a nice job describing what I’m trying to achieve in this example.
I totally recommend the Tilt gem for these things. It provides a standard interface for rendering many different template langages with the same API, lets you set custom scope and locals, lets you use yield, and is robust and fast. Sinatra is using it for templates.
Example:
require 'haml'
require 'tilt'
template = Tilt.new('path/to/file.haml')
# => #<Tilt::HAMLTemplate #file="path/to/file.haml" ...>
layout = Tilt.new('path/to/layout.haml')
output = layout.render { template.render }
This lets you yield inside the layout to get the rendered template, just like Rails. As for partials, David already described a simple and nice way to go.
But actually, if what you're writing is going to be served over HTTP, i suggest you take a look at Sinatra, which already provides templating, and has the simplest request routing you could imagine.
I've done this before, just for a quick-and-dirty template producer. The easiest way is to just render the HAML inside the parent object:
%p some haml that's interesting
= Haml::Engine.new('%p this is a test').render
%p some more template
You'll more than likely want to build some methods to make this easier--a couple of helper methods. Maybe you write one called render_file that takes a filename as an argument. That method might look something like:
def render_file(filename)
contents = File.read(filename)
Haml::Engine.new(contents).render
end
Then, your template would look more like:
%p some template
= render_file('some_filename.haml')
%p more template
Note, you will probably need to pass self to the original Haml::Engine render so that it knows how to find your render_file method.
I've had great success just using the instructions posted by David Richards in a concatenated way, without variables, like this:
= Haml::Engine.new(File.read('/Volumes/Project/file_to_include.haml')).render
There's obviously a more elegant way. But for someone who just wants to include one or two files, this should work nicely. It's a drawback that all base files using these includes have to be recompiled after some changes to the latter. It might be worthwile to just use php include if the environment allows that.
def render_file(filename)
contents = File.read('views/'+filename)
Haml::Engine.new(contents).render
end
(Adding this semi-redundant answer to show how one might incorporate the techniques from other answers.)
Include something like this in your setup code to monkey-patch the Haml library.
module Haml::Helpers
def render_haml(filename)
contents = File.read(Rails.root.join("app", "assets", "templates", filename))
Haml::Engine.new(contents).render
end
end
Then in your Haml file
.foo
= render_haml('partial.haml')
.bar
Obviously this is a Rails-ish example (because I wanted to use HAML in my asset pipeline instead of as views)... You will want to replace Rails.root.join(...) with a way to find filename in your project's templates or partials directory.

Resources