Friday, March 30, 2012

Rails 3. and rspec not doing what I expected

I'm trying to be better, at writing tests.  When I develop, especially for myself, I don't always know exactly how something will work or fit together exactly so I search with code for a while to find what I want.  It's hard to write a "red-green" test for this style.  I'm also not used to it as a lot of the work I have done in my past didn't have a test bed to do these kinds of tests.  So I'm bad at getting myself to write tests....blah, blah

So I was actually writing some tests with rspec and rails and they were failing, and I'm not expert at either rspec or rails and so a lot of things seem like "magic", ie get :index and suddenly a response variable shows up.

Anyway, I was testing a :post command and it should have been rendering a page after that.  I was trying to test the page rendered after the post.

response.should have_selector("form", :method => "post") do |form|          
   form.should have_selector("div", :class => "actions") do |div|            
     div.should have_selector("input", :value => "Create")
   end
end


And it just wasn't working, I was testing for information in the rendered page and it just wasn't there.  I dumped the response variable (puts response.inspect) and there was a lot of info there but clearly not the page I was expecting.  Then I dumped the header or head or something, can't remember and it clearly showed text that I was going to save but didn't, sorry, that said it was redirecting me.  Ahh! The answer, the post throws me to a redirect and I'm testing that page, it all makes sense! So now I'm testing that the redirect is going to the right spot and the other pages are tested a different way.

response.should redirect_to(subscribe_listing_purchases_path(Listing.last))

The end.

Sunday, March 25, 2012

Jquery, coffeescript and the javascript .html() working, and then not working

I ran into this problem where I made a form that had some jquery/javascript niceness to it that load up different forms when the users selects different links.  These forms have javascript/jquery of their own and all the code was there but it wasn't firing? WTF?

Well, it makes some sense because when the jquery code is initially run the form it's supposed to bind to isn't there.

So what now?

Answer, .live(), coffescript:

$ -> $("#my_id").live 'change', ->
if(this.checked)
$("#other_id").show()
else
$("#other_id").hide()


This makes the jquery goodness bind to all current and future instances with the given id.  Now the form that is loaded by user interaction has it's javascript functioning.


Saturday, March 24, 2012

Heroku, nginx, ec2, logs and awstat

That's a lot of crap in the title. I searched the internet far and wide for answers to why it doesn't just "work" but no dice.  So here it is, on the internet.  The answer mostly lies in the LogFormat string in the config.

I'm using heroku, I managed to get everything setup so my logs get shipped off to an ec2 instance.  Nice.

Now the problem I was having is trying to interpret the logs to get something like awstat to understand them.

Step 1, grep the log file and dump all the nginx output to a file

grep nginx file.log > nginx_only.file.log

I was trying to run something like this,

awstats.pl -config=model -output -staticlinks > awstats.model.html


And of course running into issues. First tip, take off all the arguments to awstats.pl that I was using, keep -config (which is mandatory), you'll get better error output although still not totally useful.  To generate the config file above I just ran the config script provided with the awstats tarball.

SO, clearly the output was telling me that my LogFormat is not correct. Standard apache output won't work? NO! Not from heroku it won't.

After a bunch of fiddling this seems to be working for me, some of the fields may be used incorrectly but it's a start for anyone looking

LogFormat="%time3 %host_r %other %other %host %other %other %time1 %methodurl %code %bytesd %refererquot %uaquot %virtualname"


Will match

Jan 24 12:07:53 d.b194-8831e521ea77 heroku[nginx] - 192.10.192.10 - - [24/Jan/2012:12:07:53 +0000] "GET /javascripts/application.js?1327406636 HTTP/1.1" 200 1001 "http://www.domain.com/" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" www.domain.com
 " 
One last last little note: the log has a bunch of dashes ("-"), I tried to capture those by putting a dash in the LogFormat string, this is incorrect, capture them by using %other.

The End.
So I've tried to start embracing coffeescript that is used in Rails 3.1, I guess it's the thing to do or something.

Anyway, I'm also using the jquery and that's all good and fine. The issue I was having is this:

I've got a form and I want it to be as easy as possible for the user to understand it and fill it out. I've got a dropdown box (or select) on this form and depending on the value I want to make little changes in the form take place to make the form easier for the user.

No problem, add some jquery to handle the change() event, show() or hide() somethings and shazam, things make more sense.

Great. So now the user saves the form and comes back to it to edit something and all those little changes that were made are no longer there. Hrm. Well, I could set the initial state of the form by adding a bunch of code to set the default values of the style's and whatever else needs to be changed but this is ugly and means putting style or js code in my view which I would rather not do.

So why not just add some code to handle the ready() event on the page, problem is the dom is initialized but the values in the form have not been set yet and my function relies on those values to work properly. I then fiddled around with trying to get a function to be called after the page was finished loading and rendering and all that but nothing was working well.

Then I found a tip on the internet suggesting to just call the change() function on the form element from the ready() event of the page. Seems like it wouldn't work because the values are not set but it turns out the change call is only handled after everything (well, everything that I need) is setup so boom. Fixed and no ugliness!

The coffeescript code:

$ -> $('#my_id').change()