On Mon, Apr 14, 2008 at 6:58 PM, Jamie D <[EMAIL PROTECTED]> wrote:
> Hi all, I've written an expectation for a method that converts a hash
> into a url string of name/value pairs. The problem is that the hash is
> not traversed in the same order as it is defined so I can not work out
> how to test for the correct returned string. The operation of the code
> does not require and specific order so I am not going to add a
> specific order to my method.
>
>
> # test
> def mappings_data
> {
> :shell => true,
> :ftp => 10,
> :sql => 11,
> :email => 12,
> :subdomains => 13,
> :parkeddomains => 14,
> :addondomains => 15,
> :transfer => 16
> }
> end
>
> it "should map arguments to a url" do
> @whm.map_args_to_url(mappings_data).should
>
> eql("?shell=true&ftp=10&sql=11&email=12&subdomains=13&parkeddomains=14&addondomains=15&transfer=16")
> end
>
> # implementation
> def map_args_to_url(args={})
> '?' + args.map { |k,v| "%s=%s" % [URI.encode(k.to_s),
> URI.encode(v.to_s)] }.join('&') unless args.blank?
> end
>
> # string that is returned
>
> "?parkeddomains=14&shell=true&email=12&addondomains=15&ftp=10&subdomains=13&transfer=16&sql=11"
> _______________________________________________
> rspec-users mailing list
> [email protected]
> http://rubyforge.org/mailman/listinfo/rspec-users
>
You can use the CGI library to parse the query string, and verify that
the hashes are equal.
params = {:foo => true, :bar => 12}
params_as_strings = {}
params.each_key {|key| params_as_strings[key.to_s] = params[key].to_s }
query_string = map_args_to_url params
CGI.parse(query_string.delete("?")).should == params_as_strings
(completely untested, so you'll have to mess with it I'm sure)
That's a bit ugly and verbose, so it may be a good candidate for a
custom matcher
query_string.should equal_query_string("?foo=true&bar=12")
The matcher would call CGI.parse on the actual and expected strings
and verify that they are equal.
Another thing that jumps out at me is that there may be a chance to
build a QueryParams abstraction. So instead of the above expectation,
you might do
query_params.should == QueryParams.new(:foo => true, :bar => 12)
(you would still have to write a spec verifying the QueryParams#to_s
hash->string conversion of course)
If all you're doing at this point is building that string, then a
QueryParams object is probably overkill. But I would be ready to move
to it as soon as I started to do any more logic with the query string,
such as asserting that it contains a certain key-value pair.
Like I said at the beginning, this is probably a good situation for a
custom expectation matcher to hide some of the messy details. Just
keep in mind that the thresholds for creating a custom matcher and
creating a new object are not that far apart, and creating a new
object is generally way more valuable.
(that was almost certainly a lot longer than you wanted, sorry. I've
just been sick the last couple days and needed to scratch my
list-writing itch :)
Pat
_______________________________________________
rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users