How to correctly use the Site-prism URL expansion - site-prism

I have a page object with the following setup:
class StudynoteShowPage < SitePrism::Page
set_url "/studynotes{/studynote}"
end
When I use that page
ssp = StudynoteShowPage.new
ssp.load(studynote: #s1)
I get
ArgumentError:
wrong number of arguments (given 1, expected 0)
Any ideas about that?
I've already tried single and double quotes in the set_url, but that makes no difference.
I can see that the addressable gem is included in my Gemfile.lock.

This "should" work. Could you please check the following.
You have a version of site_prism > 2.12 (Or better > 3.0),
You have addressable 2.5+
You're using Ruby 2.2+ (Better 2.5/2.6)
If you are and can re-create a SSCCE raise a Github issue (Ideally with all the code in a small clonable repo here: https://github.com/natritmeyer/site_prism/issues
We have a variety of unit tests and a couple of feature tests that validate this code works (We may have missed something though)

Related

Using a class inside module

I am new to ruby and trying to use a facility provided by a ruby gem 'combine_pdf'. As described in the documentation, I am trying to do a CombinePDF.load("file1.pdf").
However , I am getting an error
Uninitialized constant CombinePDF in X::Y ( or something similar).
The class inside which I am using combine pdf is present inside a module X::Y. And ruby is somehow also trying to look for CombinePDF in the same package. This is actually a rails project and I have combinepdf in the gemfile.
Use double colon:
::CombinePDF
It is all about constants resolution mechanizm - double colon means, you want to reference the constant, defined in the outermost scope.
It sounds like although you included combine_pdf in the Gemfile, you did not require it in the file in which you use it. You should have this in that file:
require 'combine_pdf'
Do you?

(Ruby) Error: `set_encoding': can't convert String to Hash in sinatra file (base.rb, line 1760)

I'm trying to run an example app from github. their app runs fine. which means that my setup is wrong, but I don't know what it is. this is my first time trying ruby.
what I did:
1- downloaded the code from github
2- made a gemfile:
source "https://rubygems.org"
ruby "2.0.0"
gem "sinatra", "1.4.4"
gem "haml", "4.0.3"
gem "sass", "3.2.12"
3- ran bundle install
4- when I run my .rb file (on heroku or on my computer), I get this error everytime:
/Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1760:in `set_encoding': can't convert String to Hash (String#to_hash gives Symbol) (TypeError)
from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1760:in `block in detect_rack_handler'
from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1758:in `each'
from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1758:in `detect_rack_handler'
from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/base.rb:1420:in `run!'
from /Library/Ruby/Gems/2.0.0/gems/sinatra-1.4.4/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'
--> I should signal that the github repo I'm trying to run is old (hasn't been touched since 2010)
It seems that this is an error in the used gem "sinatra".
Try to change the gemfile like this (without giving explicit version number), so that the application installs the latest version of the gems.
source "https://rubygems.org"
ruby "2.0.0"
gem "sinatra"
gem "haml"
gem "sass"
Probably there is a newer version of the sinatra gem.
Ok. so it turns out it wasn't my setup. (I tried using gems and ruby versions from 2009 and it didn't make the error go away either.)
I narrowed it down by gradually commenting things out in the script (since ruby wouldn't give me a line in my own files, only in sinatra files, I thought at first it wasn't due to my code).
--> it was a single line of code that, now that I commented it out in my script, made the error disappear forever with seemingly no negative side effects. (see code below).
If someone can briefly comment on that method (is it some kind of sinatra framework callback, for error handling a call to a nonexistent method? I assume this since it's never called in my files!) and why it could cause the error described in the question, I will pick their answer, otherwise I will pick this (my) answer. (just write anything you know or can find about this method and I'll pick your answer, Thanks).
def method_missing(methId)
method_name=methId.id2name.intern
if #lists.respond_to? method_name
#lists.send(method_name).pick
else
# method_name # line that caused the error in the sinatra source files.
end
end
================================================
so here's my own quick research on method_missing ... trying to learn ruby a bit here:
some info about method_missing:
http://www.alfajango.com/blog/method_missing-a-rubyists-beautiful-mistress/#/when-to-use-method-missing
http://rubylearning.com/blog/2010/10/07/do-you-know-rubys-chainsaw-method/
second link is a great intro.
basically method_missing is, yes, a kind of error handler for calling nonexistent methods. it's a ruby language thing (it calls method_missing when it can't find the method). so it's not tied to a framework, just to ruby.
besides simple error handling, one common usage for it is to be able define actions according to the (non-existent) method name (make up actions based on the nonexistent method name!), for example in the case where you have a great number of methods that do very repetitive things and you can deduce/base their behavior on their name.
a way to limit your pool of "methods you're going to make up behavior for, on the spot" is to have an if with a regular expression match (or in our case a match in a predefined list of items). if it's not matched, then you can for example throw an exception yourself or just return to see what happens next in the calling code.
so here in our code:
if the method name doesnt exist, they check if it exists in a list and act accordingly (they return a list, picked among #lists).
but if it is not found in #lists … they return that very method name, a string, that we didnt have a match for.
...but now the question is: --> how is the calling code dealing with that return value? (obviously not well, it seems to expect a hash or an array, not a method name string) a safe way to deal with "not finding a match for your nonexistent method" is to call super, to resume normal execution of the calling code (according to first link).
so one question remains: was it a good idea to return the method name? would returning the method name ever work? or was it really wrong, and super (or nothing) should be put in its place?
… my temporary conclusion is that --> you shouldn't return a list sometimes and a string some other times. so it would be a plain mistake, that surprisingly never caused problems or was never found in the original repo...

Storing version number in a Ruby Gem

How should I store the version number of my code inside a ruby gem?
I've seen two techniques in the wild:
<gem root>/VERSION which only contains your semver.
<gem root>/lib/your_gem/version.rb which contains the following code:
module IfYourCodeIsInAModule
class YourGem
VERSION="0.0.1"
end
end
I like 1. because it's really obvious. I like 2. because it's part of my code, I can write to logs with my version number easily.
I don't like 1. because if I want to access the version number from within my code I have to do a file read (not the worst thing ever), I don't like 2. because if my core class extends from another class then I have to have that decendency in the version.rb too (or else get a superclass mismatch) - eg.
module IfYourCodeIsInAModule
class YourGem < OtherWork
VERSION = "0.0.1"
end
end
When you require this file from your actual code for runtime it's all good. When you include it in your gemspec you suddenly need to require 'other_work' to get your Version number!
I'm happy to go and roll my own solution, but this can't be a new problem, what's the community doing, and what's the general wisdom on this?
I am no expert on gem VERSION ethnology, but perhaps this non-expertise makes me all the more average and better suited to answer the questions on "general wisdom".
So, general wisdom is, use Bundler. And once you create your gem by bundle gem my_gem_name, you will see that the bundler automatically creates lib/my_gem_name/version.rb file and requires it from your lib/my_gem_name.rb. So I would suggest that if you decide not to use bundler and roll your own gem on your own, you still should keep a separate version.rb file containing only
module MyGemName
VERSION = "0.0.1"
end
That is, straight under the main module. You then load the version.rb from lib/my_gem_name.rb. Of course, if your code is organized in a more alien way, then you need to improvize more.

Are there any RSpec HTML tag matchers extensions for sinatra?

I've been using for Rails apps I've been maintaining the hpricot_matchers and most recently rspec_tag_matchers as matcher implementations to test strings with nested tags inside (like, let's say, HTML or XML). Specially the last one is really good, since it uses Nokogiri.
Recently I started developing in Sinatra, and of course, I bundled rspec in it. All is nice and neat, til I found out I don't have certain matchers available like the have_tag (which check tags and attributes values). Well, this would be really great to have in Sinatra, and the above mentioned gems are not usable, since they have a rspec-rails dependency, which has a rails dependency.
So the question would be: is there any tool available for Sinatra which accomplishes the same task? Any Sinatra matchers out in the open? Couldn't find any, though.
Actually found out an extension that does the job...
https://github.com/kucaahbe/rspec-html-matchers
Should have looked a little bit more. I haven't checked whether it covers everything that the rails rspec matcher helpers do, but most of the important ones are there, including the very valuable have_tag. One thing, though: the specification for both is a bit different when it comes to nested conditions in sub-tags:
rspec_tag_matchers(rails3):
text.should have_tag("p") do |paragraph|
paragraph.should have_tag("strong")
end
rspec_html_matchers(sinatra/...):
text.should have_tag("p") do
with_tag("strong")
end
I think you are looking for this...
Code Example for Rspec Matchers
Code looks like this there...
# File lib/sinatra/tests/rspec/matchers.rb, line 52
def have_a_page_header(expected, tag = 'h2')
simple_matcher("have an '#{tag}' page header with [#{expected.inspect}]") do |given, matcher|
given.should have_tag(tag, expected, :count => 1)
end
end
The point is: You can always create your own matchers.
Hope that helps.
You can use Capybara when testing a sinatra app (or any rack app, for that matter). Capybara includes several matchers that would probably meet your needs:
have_selector('table tr')
have_xpath('//table/tr')
have_css('table tr.foo')

Where can I find an actively developed lint tool for Ruby?

Most of the code I write is in Ruby, and every once in a while, I make some typo which only gets caught after a while. This is irritating when I have my scripts running long tasks, and return to find I had a typo.
Is there an actively developed lint tool for Ruby that could help me overcome this? Would it be possible to use it across a system that works with a lot of source files, some of them loaded dynamically?
Take this snippet as an example:
a = 20
b = 30
puts c
To win bounty, show me a tool that will detect the c variable as not created/undefined.
ruby -c myfile.rb will check for correct Ruby syntax.
Reek checks Ruby code for common code smells.
Roodi checks Ruby code for common object-oriented design issues.
Flog can warn you about unusually complex code.
[Plug] If your project is in a public Github repository, Caliper can run the latter three tools and others on your code every time you commit. (Disclaimer: I work on Caliper)
You could give Diamondback Ruby a try. It does a static typecheck of Ruby code, and will thus blame you for using an undefined variable.
While DRuby is an ongoing research project, it already works quite well for small, self-contained Ruby scripts. Currently, it is unable to analyze much of the Ruby standard library “out-of-the-box”. Currently they are working toward typing Ruby on Rails (see their most recent papers).
RubyMine (http://www.jetbrains.com/ruby) does the trick:
alt text http://img707.imageshack.us/img707/5688/31911448.png
None of the below will do all the analysis that RubyMine does.
NetBeans Ruby pack
Aptana RadRails
gVIM (with syntastic plugin by scrooloose)
Each of these has the capacity to identify syntax errors such as wrong number of parentheses, too many defs, ends, braces, etc. But none will identify invalid method calls the way RubyMine does.
Here's why: it's difficult.
Since Ruby is extremely dynamic (and methods like 'c' could easily be generated on the fly), any editor that tries to identify non-existent variables/methods would need to have a large part of the entire evironment loaded and multiple program flow paths constantly tested in order to get accurate 'validity' results. This is much more difficult than in Java where almost all programming is static (at least it was when I dropped that hat).
This ability to easily generate methods on the fly is one of the reasons the community holds testing to such high esteem. I really do reccomend you try testing as well.
Have a look at RuboCop. It is a Ruby code style checker based on the Ruby Style Guide. It's maintained pretty actively and supports all major Ruby implementations. It works well with Ruby 1.9 and 2.0 and has great Emacs integration.
Yes. Test::Unit
Ok, I know you already know this and that in some sense this is a non-helpful answer, but you do bring up the negative consequence of duck typing, that there kind of is (at this time) no way around just writing more tests than something like Java might need.
So, for the record, see Test::Unit in the Ruby Standard Library or one of the other test frameworks.
Having unit tests that you can run and rerun is the best way to catch errors, and you do need more of them (tests, not errors :-) in dynamic languages like Ruby...
nitpick might be what you're lookng for.
With this code:
class MyString < String
def awesome
self.gsub("e", "3").gsub("l", "1").uppercase
end
end
puts MyString.new("leet").awesome
... it outputs:
$ nitpick misspelling.rb
*** Nitpick had trouble loading "misspelling.rb":
NoMethodError undefined method `uppercase' for "133t":MyString
Nothing to report boss! He's clean!
Have not used it yet, but sounds promising (will update when I've tested this).
https://github.com/michaeledgar/laser
Static analysis and style linter for Ruby code.
Pelusa is nice, but is working in rubinius only. This shouln't be a proplem for people familar with RVM though.
avdi#lazarus:~$ irb
>> a = 20
=> 20
>> b = 30
=> 30
>> puts c
NameError: undefined local variable or method `c' for main:Object
from (irb):3
>>
There ya go, the tool is called "IRB". Do I get the bounty?
I'm only half joking. I wrote this second answer to hopefully drive home the point that in Ruby, if you want to know that something is defined or not, you have to run the code.

Resources