Patrick J. Collins
2011-Nov-03 22:36 UTC
[rspec-users] problems matching generated html output...
So, I am writing tests for a presenter class that outputs html markup. I have a method that does something like this: def output things.map do |thing| content_tag :div, :id => thing[:id] do [content_tag :p, thing[:body_1], content_tag :p, thing[:body_2].join.html_safe end end.join.html_safe end ... Then my spec is something like this: it "returns markup" do @presenter.stubs(:things).returns({:id => "an_id", :body_1 => "hello", :body_2 => "goodbye"}) @presenter.output.should == filter_for_html(" <div id="an_id"> <p>hello</p> <p>goodbye</p> </div> ") end and I made this filter_for_html helper method which allows me to not care about whitespace... So that just does: def filter_for_html(markup) markup.squeeze(" ").strip.gsub(/\n\s+/, "") end And this effctively strips out all the whitespace and gives me a string like: "<div id="an_id"><p>hello</p><p>goodbye</p></div>" ... -- END OF BACKGROUND EXPLANATION -- Now for my question--- I have two problems and am not sure what the best to solve either one is: 1) The match fails because content_tag apparently inserts in a few \n''s here and there. 2) My background explanation was actually quite simplified, and my presenter class is actually rendering some haml partials, and something like %ul.foo turns into <ul class=''foo''> (note the SINGLE QUOTES).. So my test fails because my expectation code uses double classes 3) Some of the text generated via the partials is calling things like .humanize which capitalize text and I am not really concerned about those details in my test.......... So the way I got my test passing is to do: @presenter.output.gsub("\n", "").gsub("''", "\"").downcase.should == filter_for_html('' ... same content as before ... '') Which I don''t know about you, but that makes me go "ewwwwwwwwww". And makes all the RSpec readibility go out the window. Is there something I should be doing with a custom matcher or something to test for case-indifferent text, ignore whitespace and \n, and be quote indifferent? Thanks. Patrick J. Collins http://collinatorstudios.com
Patrick J. Collins
2011-Nov-03 23:07 UTC
[rspec-users] problems matching generated html output...
> So, I am writing tests for a presenter class that outputs html markup. >Actually now that I am thinking about it.. Would you guys recommend that I use something like Nokogiri to parse the content and test for things like number of children, classes, ids, etc, rather than just comparing the raw HTML? Patrick J. Collins http://collinatorstudios.com
On 3 Nov 2011, at 22:36, Patrick J. Collins wrote:> So, I am writing tests for a presenter class that outputs html markup. > > I have a method that does something like this: > > def output > > things.map do |thing| > > content_tag :div, :id => thing[:id] do > [content_tag :p, thing[:body_1], > content_tag :p, thing[:body_2].join.html_safe > end > > end.join.html_safe > > end > > ... > > Then my spec is something like this: > > it "returns markup" do > > @presenter.stubs(:things).returns({:id => "an_id", :body_1 => "hello", > :body_2 => "goodbye"}) > > @presenter.output.should == filter_for_html(" > > <div id="an_id"> > <p>hello</p> > <p>goodbye</p> > </div> > ") > end > > and I made this filter_for_html helper method which allows me to not care about > whitespace... So that just does: > > def filter_for_html(markup) > markup.squeeze(" ").strip.gsub(/\n\s+/, "") > end > > And this effctively strips out all the whitespace and gives me a string like: > "<div id="an_id"><p>hello</p><p>goodbye</p></div>" > > ... > > -- END OF BACKGROUND EXPLANATION -- > > Now for my question--- I have two problems and am not sure what the best to > solve either one is: > > 1) The match fails because content_tag apparently inserts in a few \n''s here > and there. > > 2) My background explanation was actually quite simplified, and my presenter > class is actually rendering some haml partials, and something like %ul.foo > turns into <ul class=''foo''> (note the SINGLE QUOTES).. So my test fails > because my expectation code uses double classes > > 3) Some of the text generated via the partials is calling things like > .humanize which capitalize text and I am not really concerned about those > details in my test.......... > > > So the way I got my test passing is to do: > > @presenter.output.gsub("\n", "").gsub("''", "\"").downcase.should == filter_for_html('' ... same content as before ... '') > > Which I don''t know about you, but that makes me go "ewwwwwwwwww". And makes > all the RSpec readibility go out the window. Is there something I should be > doing with a custom matcher or something to test for case-indifferent text, > ignore whitespace and \n, and be quote indifferent? > > Thanks. > > Patrick J. Collins > http://collinatorstudios.comI realise this isn''t the answer you''re looking for, but I''m curious: where did you get the idea that a presenter should know anything about HTML? cheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne
Patrick J. Collins
2011-Nov-03 23:25 UTC
[rspec-users] problems matching generated html output...
> I realise this isn''t the answer you''re looking for, but I''m curious: where > did you get the idea that a presenter should know anything about HTML?Maybe I am using the wrong terminology then. I always thought presenters were classes that output presentational content... If you have a view with a lot of dynamic content, the conditional logic ends up building to the point where the view is unreadable, and if you try to refactor out into helper methods, you end up having something like module MyHelper def something(lol) modify_lol(lol) end def modify_lol(lol) do_something_else_with_lol(lol) end ... etc end A class helps to eliminate this problem by giving you a way to instantiate with instance variables and cut down on having pass around the same variable to multiple helpers...... I''ve always called that a presenter, and in this case it deals with HTML. Am I totally on crack? Patrick J. Collins http://collinatorstudios.com
On Nov 3, 2011, at 4:07 PM, Patrick J. Collins wrote:>> So, I am writing tests for a presenter class that outputs html markup. >> > Actually now that I am thinking about it.. Would you guys recommend that I use > something like Nokogiri to parse the content and test for things like number of > children, classes, ids, etc, rather than just comparing the raw HTML?Yes, definitely. Also you might be interested in https://github.com/nakajima/elementor although I haven''t used it in a long time so I don''t know how up to date it is. As far as your other question goes about how to use presenters, you probably don''t want them emitting HTML. Instead you want the presenter to provide a simpler interface to some commonly accessed data that you don''t think belongs on the model. An example might be class UserPresenter def initialize(user) @user = user end def full_name @user.first_name + '' '' + @user.last_name end end Ignoring whether this is an appropriate case for using a presenter, you can see what I''m accomplishing here. And hopefully you can imagine it being more useful if there are multiple models involved. A presenter is basically the facade pattern used specifically for presentation logic. Pat http://c2.com/cgi/wiki?FacadePattern http://blog.jayfields.com/2007/03/rails-presenter-pattern.html
On 3 Nov 2011, at 23:25, Patrick J. Collins wrote:>> I realise this isn''t the answer you''re looking for, but I''m curious: where >> did you get the idea that a presenter should know anything about HTML? > > Maybe I am using the wrong terminology then. I always thought presenters were > classes that output presentational contentWell, in any discussion I''ve seen of the pattern, that''s the job of the view. MVP / Passive View[1][2] is quite a well-established pattern in curly-bracket languages, and the presenter''s job in that pattern is to tell the view, at a logical level, what to show. The view is then just left with the simple job of showing it. The idea being that you could use the same presenter with a view for a web app, a view for a rich-client GUI, or a view for a mobile app. In theory. This makes them both much easier to test. Steve Klabnik has been writing about their application in the Ruby / Rails world recently[3] [1] http://martinfowler.com/eaaDev/PassiveScreen.html [2] http://www.objectmentor.com/resources/articles/TheHumbleDialogBox.pdf [3] http://blog.steveklabnik.com/2011/09/06/the-secret-to-rails-oo-design.html cheers, Matt -- Freelance programmer & coach Author, http://pragprog.com/book/hwcuc/the-cucumber-book (with Aslak Helles?y) Founder, http://relishapp.com +44(0)7974430184 | http://twitter.com/mattwynne -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20111104/3ddc3394/attachment.html>