Hi, I am quite new to Rspec. I want to use Rspec to test my existing Code. I start from Models (Unit Testing). Here i want your help on a issue. Here is model/user_spec.rb describe User do before(:each) do @user=User.new @user.id=''2'' @user.email=''kkkk at gmail.com'' @user.password=''1234'' @user.crypted_password= ''21066966a0578362e2115f3561bd4f144520ccd2'' @user.salt= ''574f09d3ae2473105567eab77ba9d3ae08ed40df'' @user.remember_token= '''' @user.remember_token_expires_at= '''' @user.name= ''kaleem'' @user.company_id=''2'' @user.title= '''' @user.active= ''1'' @user.reset_password_token= '''' end it "should authenticate with valid email,password and approved company" do User.authenticate(@user.email, @user.password).should_not be_nil end it "should NOT authenticate with INvalid email" do @user.email=nil User.authenticate(@user.email, @user.password).should be_nil end it "should NOT authenticate with INvalid password" do @user.password=nil User.authenticate(@user.email, @user.password).should be_nil end it "should remember me" do @user.remember_me @user.remember_token.should_not be_nil @user.remember_token_expires_at.should_not be_nil end it "Remember Token time should be less than Token expires time" do @user.remember_token?.should be_true end it "should forget me" do @user.forget_me @user.remember_token.should be_nil @user.remember_token_expires_at.should be_nil end end Now Questions: 1) is my approach or way of writing specs is right??? 2) How can i make specs for such a model action def activate! self.update_attribute(:active, true) end Thank you :) -- Posted via http://www.ruby-forum.com/.
On 11/02/2009, at 8:51 AM, Kaleem Ullah wrote:> Hi, > > I am quite new to Rspec. I want to use Rspec to test my existing > Code. I > start from Models (Unit Testing). Here i want your help on a issue. > > Here is model/user_spec.rb > > describe User do > before(:each) do > @user=User.new > @user.id=''2'' > @user.email=''kkkk at gmail.com'' > @user.password=''1234'' > @user.crypted_password= ''21066966a0578362e2115f3561bd4f144520ccd2'' > @user.salt= ''574f09d3ae2473105567eab77ba9d3ae08ed40df'' > @user.remember_token= '''' > @user.remember_token_expires_at= '''' > @user.name= ''kaleem'' > @user.company_id=''2'' > @user.title= '''' > @user.active= ''1'' > @user.reset_password_token= '''' > end > > it "should authenticate with valid email,password and approved > company" do > User.authenticate(@user.email, @user.password).should_not be_nil > end > > it "should NOT authenticate with INvalid email" do > @user.email=nil > User.authenticate(@user.email, @user.password).should be_nil > end > > it "should NOT authenticate with INvalid password" do > @user.password=nil > User.authenticate(@user.email, @user.password).should be_nil > end > > it "should remember me" do > @user.remember_me > @user.remember_token.should_not be_nil > @user.remember_token_expires_at.should_not be_nil > end > > it "Remember Token time should be less than Token expires time" do > @user.remember_token?.should be_true > end > > it "should forget me" do > @user.forget_me > @user.remember_token.should be_nil > @user.remember_token_expires_at.should be_nil > end > end > > Now Questions: > 1) is my approach or way of writing specs is right??? > 2) How can i make specs for such a model action > > def activate! > self.update_attribute(:active, true) > end > > Thank you :)Hi Kaleem. All of that looks pretty good so far, though you shouldn''t be setting the "id" attribute of an AR model: @user.id = ''2'' I suggest using the following format for creating your User object: before(:each) do @user = User.new( :email => ''kkkk at gmail.com'', :password => ''1234'', # ..etc.. ) end To spec your #activate! , why not do something like this?: it ''should activate the user'' do @user.active.should be_false @user.activate! @user.active.should be_true end Cheers, Nick
On Feb 11, 2009, at 8:51 AM, Kaleem Ullah wrote:> Hi, > > I am quite new to Rspec. I want to use Rspec to test my existing > Code. I > start from Models (Unit Testing). Here i want your help on a issue. > > Here is model/user_spec.rb > > describe User do > before(:each) do > @user=User.new > @user.id=''2'' > @user.email=''kkkk at gmail.com'' > @user.password=''1234'' > @user.crypted_password= ''21066966a0578362e2115f3561bd4f144520ccd2'' > @user.salt= ''574f09d3ae2473105567eab77ba9d3ae08ed40df'' > @user.remember_token= '''' > @user.remember_token_expires_at= '''' > @user.name= ''kaleem'' > @user.company_id=''2'' > @user.title= '''' > @user.active= ''1'' > @user.reset_password_token= '''' > endYou could benefit from a factory / data builder. See FixtureReplacement, Fixjour, Factory girl, one of the many others out there which would build this stuff *once* for you.> > > it "should authenticate with valid email,password and approved > company" do > User.authenticate(@user.email, @user.password).should_not be_nil > end > > it "should NOT authenticate with INvalid email" do > @user.email=nil > User.authenticate(@user.email, @user.password).should be_nil > end > > it "should NOT authenticate with INvalid password" do > @user.password=nil > User.authenticate(@user.email, @user.password).should be_nil > end > > it "should remember me" do > @user.remember_me > @user.remember_token.should_not be_nil > @user.remember_token_expires_at.should_not be_nil > end > > it "Remember Token time should be less than Token expires time" do > @user.remember_token?.should be_true > end > > it "should forget me" do > @user.forget_me > @user.remember_token.should be_nil > @user.remember_token_expires_at.should be_nil > end > end > > Now Questions: > 1) is my approach or way of writing specs is right???Remember: there is no right way of doing things. Does it work for you (and your team)? Is it clear?> > 2) How can i make specs for such a model action > > def activate! > self.update_attribute(:active, true) > endspec1: @user.activate! @user.should be_active spec 2: @user.should_not be_active Scott
Scott Taylor wrote:> On Feb 11, 2009, at 8:51 AM, Kaleem Ullah wrote: > >> @user=User.new >> @user.active= ''1'' >> @user.reset_password_token= '''' >> end > > You could benefit from a factory / data builder. See > FixtureReplacement, Fixjour, Factory girl, one of the many others out > there which would build this stuff *once* for you.Kaleem, I recently installed nakajima-acts_as_fu (0.0.3) gem. This provides a rather painless way of specifying ActiveRecord model schemata on the fly in your specifications. You might find it helpful to look into this. You will discover that some people favour mocks and stubs when dealing with AR models in tests/specifications and some favour hitting the database. Once you decide on your own preference in this matter the choice of approach is somewhat simplified. -- Posted via http://www.ruby-forum.com/.
Nick Hoffman wrote:> To spec your #activate! , why not do something like this?: > > it ''should activate the user'' do > @user.active.should be_false > @user.activate! > @user.active.should be_true > end > >Thanks for your reply Hoffman :) I did the same but it gives error like "#23000Duplicate entry ''kkkkk at gmail.com Insert INTO (...) Values(...)". It should do update not Insert. But when i try call it with a new instance of user (with no values assigned to any user attribute) then it works. i.e. it "should activate the user" do @user1=User.new @user1.activate! end This works. I think i have to erase all the User attributes from "before (:each)" and only assigned it in Examples which required it. am i right ? Thanks -- Posted via http://www.ruby-forum.com/.
James Byrne wrote:> I recently installed nakajima-acts_as_fu (0.0.3) gem. This provides a > rather painless way of specifying ActiveRecord model schemata on the fly > in your specifications. You might find it helpful to look into this. > > You will discover that some people favour mocks and stubs when dealing > with AR models in tests/specifications and some favour hitting the > database. Once you decide on your own preference in this matter the > choice of approach is somewhat simplified.Hi james byrne, Good to know that.I will surely look for this gem...... Thanks :) -- Posted via http://www.ruby-forum.com/.
Scott Taylor wrote:> On Feb 11, 2009, at 8:51 AM, Kaleem Ullah wrote: > >> @user=User.new >> @user.active= ''1'' >> @user.reset_password_token= '''' >> end > > You could benefit from a factory / data builder. See > FixtureReplacement, Fixjour, Factory girl, one of the many others out > there which would build this stuff *once* for you.Hi Scott Taylor, I am in need of such data builders. So nice of you... :) -- Posted via http://www.ruby-forum.com/.
Kaleem Ullah wrote:> Scott Taylor wrote:>> You could benefit from a factory / data builder. See >> FixtureReplacement, Fixjour, Factory girl, one of the many others out >> there which would build this stuff *once* for you.> I am in need of such data builders.I recently thumped the square peg of FixtureDependencies into the round hole of Merb''s RSpec. http://github.com/jeremyevans/fixture_dependencies/tree/master I can answer questions about it if anyone wants to try it. Except how to make it do rake db:fixtures:load. Does anyone know that one? -- Phlip
Hi all, Below is my model action. def activate! self.update_attribute(:active, true) end here is spec/models/user_spec.rb describe User do before(:each) do @user=User.new(:email=>''kkk at gmail.com'',:password=''1234''....,) end This is my spec. it "should activate the user" do @user.activate! @user.active.should be_true end but it gives error like "#23000Duplicate entry ''kkkkk at gmail.com Insert INTO (...) Values(...)". It should do update not Insert. But when i try call it with a new instance of user (with no values assigned to any user attribute) then it works. i.e. it "should activate the user" do @user_1=User.new @user_1.activate! @user_1.active.should be_true end I think i have to erase all the User attributes from "before (:each)" and only assigned it in Examples which required it. am i right ? Thanks -- Posted via http://www.ruby-forum.com/.
kaleem, method new does not run your model validations, neither does your provided activate! implementation. but save indeed does. my guess is your mixing several contexts (cases, situations) in your single spec. Try decoupling all with more granular examples and you''ll get to save shore :-) cheers, joaquin -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20090212/b9cc952d/attachment.html>
Hi, I am trying to write custom matcher which accepts block to spec views with forms/fieldsets/inputs eg view: --- <form action=''/users''> <fieldset> <legend>Personal Information</legend> <ol> <li> <label>First name</label> <input type="text" name="user[first_name]" /> </li> ... </ol> </fieldset> </form> spec: --- it "should have form with input fields" do render ... response.should have_form(users_path) do with_field_set ''Personal Information'' do with_text_field ''First name'', ''user[first_name]'' ... end end end matches? of have_form: --- def matches?(response, &block) @block = block if block response.should @scope.have_tag(''form[action=?]'', @action) do @block.call.matches?(response) end end matches? of have_field_set: --- def matches?(response, &block) @block = block if block response.should @scope.with_tag(''fieldset'') do @scope.with_tag(''legend'', @legend) if @legend @scope.with_tag(''ol'') do @block.call.matches?(response) end end end but I get: NoMethodError in ''/users/new should have form with input fields'' undefined method `matches?'' for true:TrueClass ./spec/views/users/../../custom_ui_matchers/with_field_set.rb:10:in `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:11:in `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:10:in `matches?'' ./spec/views/users/new.html.haml_spec.rb:17: /usr/lib64/ruby/1.8/timeout.rb:53:in `timeout'' something wrong with yielding block? Gist: http://gist.github.com/62562 Thanks in advance, Yury
On Thu, Feb 12, 2009 at 5:52 AM, Yury Kotlyarov <yura at brainhouse.ru> wrote:> Hi, > > I am trying to write custom matcher which accepts block to spec views with > forms/fieldsets/inputs eg > > view: > --- > <form action=''/users''> > <fieldset> > <legend>Personal Information</legend> > <ol> > <li> > <label>First name</label> > <input type="text" name="user[first_name]" /> > </li> > ... > </ol> > </fieldset> > </form> > > spec: > --- > > it "should have form with input fields" do > render ... > response.should have_form(users_path) do > with_field_set ''Personal Information'' do > with_text_field ''First name'', ''user[first_name]'' > ... > end > end > end > > matches? of have_form: > --- > > def matches?(response, &block) > @block = block if block > response.should @scope.have_tag(''form[action=?]'', @action) do > @block.call.matches?(response) > end > end matches? of have_field_set: --- > > def matches?(response, &block) > > @block = block if block > response.should @scope.with_tag(''fieldset'') do > @scope.with_tag(''legend'', @legend) if @legend > @scope.with_tag(''ol'') do > @block.call.matches?(response) > end > end > end but I get: NoMethodError in ''/users/new should have form with input > fields'' undefined method `matches?'' for true:TrueClass > ./spec/views/users/../../custom_ui_matchers/with_field_set.rb:10:in > `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:11:in > `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:10:in > `matches?'' ./spec/views/users/new.html.haml_spec.rb:17: > /usr/lib64/ruby/1.8/timeout.rb:53:in `timeout'' something wrong with yielding > block? Gist: http://gist.github.com/62562 Thanks in advance, YuryWhat does initialize look like?
David Chelimsky wrote:> On Thu, Feb 12, 2009 at 5:52 AM, Yury Kotlyarov <yura at brainhouse.ru> wrote: > >> Hi, >> >> I am trying to write custom matcher which accepts block to spec views with >> forms/fieldsets/inputs eg >> >> view: >> --- >> <form action=''/users''> >> <fieldset> >> <legend>Personal Information</legend> >> <ol> >> <li> >> <label>First name</label> >> <input type="text" name="user[first_name]" /> >> </li> >> ... >> </ol> >> </fieldset> >> </form> >> >> spec: >> --- >> >> it "should have form with input fields" do >> render ... >> response.should have_form(users_path) do >> with_field_set ''Personal Information'' do >> with_text_field ''First name'', ''user[first_name]'' >> ... >> end >> end >> end >> >> matches? of have_form: >> --- >> >> def matches?(response, &block) >> @block = block if block >> response.should @scope.have_tag(''form[action=?]'', @action) do >> @block.call.matches?(response) >> end >> end matches? of have_field_set: --- >> >> def matches?(response, &block) >> >> @block = block if block >> response.should @scope.with_tag(''fieldset'') do >> @scope.with_tag(''legend'', @legend) if @legend >> @scope.with_tag(''ol'') do >> @block.call.matches?(response) >> end >> end >> end but I get: NoMethodError in ''/users/new should have form with input >> fields'' undefined method `matches?'' for true:TrueClass >> ./spec/views/users/../../custom_ui_matchers/with_field_set.rb:10:in >> `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:11:in >> `matches?'' ./spec/views/users/../../custom_ui_matchers/have_form.rb:10:in >> `matches?'' ./spec/views/users/new.html.haml_spec.rb:17: >> /usr/lib64/ruby/1.8/timeout.rb:53:in `timeout'' something wrong with yielding >> block? Gist: http://gist.github.com/62562 Thanks in advance, Yury >> > > What does initialize look like? > >initialize for have_form: class HaveForm def initialize(action, scope, &block) @action, @scope, @block = action, scope, block end ... end def have_form(action, &block) HaveForm.new(action, self, &block) end initialize for have_field_set: class WithFieldSet def initialize(scope, legend = nil, &block) @scope, @legend, @block = scope, legend, block end end def with_field_set(legend = nil, &block) WithFieldSet.new(self, legend, &block) end btw I put it on gist: http://gist.github.com/62562
SOLVED! just need to pass matched result to inner block. gist: http://gist.github.com/62562 Many thanks, Yury
Yury Kotlyarov wrote:> SOLVED! just need to pass matched result to inner block. gist: > http://gist.github.com/62562 > > Many thanks, > Yury >I was wrong. It yields just one last line from the inner block. It passes following: it "should have form to create a new user" do render ''/users/new'' response.should have_form(users_path) do with_field_set ''Personal Information'' do with_text_field ''wrong'', ''wrong'' # there is no such field with_text_field ''First Name'', ''user[first_name]'' end end end gist: http://gist.github.com/62562 TIA, Yury
Yury Kotlyarov wrote:> it "should have form with input fields" do > render ... > response.should have_form(users_path) do > with_field_set ''Personal Information'' do > with_text_field ''First name'', ''user[first_name]'' > ... > end > end > endThe minor problem with that system is it forces your test to say exactly what the code says. That''s not "driven" development! If you can forbear to use matchers (shocked gasp!), at my day-job we match blocks all the time with assert2''s new xpath system: require ''assert2/xpath'' assert_xhtml response xpath :form, :action => users_path do xpath :fieldset, ?. => ''Personal Information'' do xpath :input, :type => ''text'', :name => ''user[first_name]'' and xpath :input, :type => ''text'', :name => ''user[last_name]'' end end From there, wrapping the xpath() calls up into kewt with_text_field() macros would be trivial. They could also absolves the redundant ''user[]'' text on the names, for example. If any inner xpath() fails, there, the fault diagnostic contains a formatted & indented copy of the HTML block under inspection. The entire page would not spew out! Only the <form> or <fieldset> would. -- Phlip
On Fri, Feb 13, 2009 at 1:53 PM, Phlip <phlip2005 at gmail.com> wrote:> Yury Kotlyarov wrote: > >> it "should have form with input fields" do >> render ... >> response.should have_form(users_path) do >> with_field_set ''Personal Information'' do >> with_text_field ''First name'', ''user[first_name]'' >> ... >> end >> end >> end > > The minor problem with that system is it forces your test to say exactly > what the code says. That''s not "driven" development! > > If you can forbear to use matchers (shocked gasp!), at my day-job we match > blocks all the time with assert2''s new xpath system: > > require ''assert2/xpath'' > > assert_xhtml response > > xpath :form, :action => users_path do > xpath :fieldset, ?. => ''Personal Information'' do > xpath :input, :type => ''text'', :name => ''user[first_name]'' and > xpath :input, :type => ''text'', :name => ''user[last_name]'' > end > endHey Philip, This looks pretty cool. I wonder if you''d have any interest in making this a bit more rspec-friendly? Something like an option to run it like this: expect_xpath do xpath :form, :action => users_path do xpath :fieldset, ?. => ''Personal Information'' do xpath :input, :type => ''text'', :name => ''user[first_name]'' and xpath :input, :type => ''text'', :name => ''user[last_name]'' end end end> > From there, wrapping the xpath() calls up into kewt with_text_field() macros > would be trivial. They could also absolves the redundant ''user[]'' text on > the names, for example. > > If any inner xpath() fails, there, the fault diagnostic contains a formatted > & indented copy of the HTML block under inspection. The entire page would > not spew out! Only the <form> or <fieldset> would. > > -- > Phlip > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
David Chelimsky wrote:> This looks pretty cool. I wonder if you''d have any interest in making > this a bit more rspec-friendly? Something like an option to run it > like this: > > expect_xpath doIt''s on my do-list, but... ...are pluggable matchers as hard to write as the OP implied? How would you fix his problem? I need to know that before diving into the spaghetti that Ruby inevitably generates, just below every kewt DSL!
Phlip wrote:> David Chelimsky wrote: > >> This looks pretty cool. I wonder if you''d have any interest in making >> this a bit more rspec-friendly? Something like an option to run it >> like this: >> >> expect_xpath do > > It''s on my do-list, but... > > ...are pluggable matchers as hard to write as the OP implied? How > would you fix his problem? I need to know that before diving into the > spaghetti that Ruby inevitably generates, just below every kewt DSL! >The major problem is fixed: http://github.com/yura/howto-rspec-custom-matchers/ But there are still few open questions in README.rdoc Regards, Yury
Yury Kotlyarov wrote:> The major problem is fixed: > http://github.com/yura/howto-rspec-custom-matchers/Apologies if I missed something, but is that a howto or a library? Do I git it and run it to ... learn to customize matchers?
Phlip wrote:> Yury Kotlyarov wrote: > >> The major problem is fixed: >> http://github.com/yura/howto-rspec-custom-matchers/ > > Apologies if I missed something, but is that a howto or a library? Do > I git it and run it to ... learn to customize matchers? >RSpec is a library ;-) And I have some issues with writing custom matchers using rspec. Now I fixed my major showstopper but still have open questions in the README.rdoc. Of course I hope this project will help others to avoid issues I faced.
>>> http://github.com/yura/howto-rspec-custom-matchers/> RSpec is a library ;-)Please try again: What is that source code drop. A website? A library? or something else?
Phlip wrote:>>>> http://github.com/yura/howto-rspec-custom-matchers/ > >> RSpec is a library ;-) > > Please try again: What is that source code drop. A website? A library? > or something else? >ok - from README: The project aims to encourage feedback on the best practices of creating custom expectation matchers and specs for them. Does it make sense?
Yury Kotlyarov wrote:>>>>> http://github.com/yura/howto-rspec-custom-matchers/> The project aims to encourage feedback on the best practices of creating > custom expectation matchers and specs for them. > > Does it make sense?That just says it''s a "project". One git clone later... It is a Rails 2.3.0 website! TX; I will now go spelunking down inside it for a while. Wish me luck! (-;
Phlip wrote:> Yury Kotlyarov wrote: > >>>>>> http://github.com/yura/howto-rspec-custom-matchers/ > >> The project aims to encourage feedback on the best practices of >> creating custom expectation matchers and specs for them. >> >> Does it make sense? > > That just says it''s a "project". > > One git clone later... It is a Rails 2.3.0 website! > > TX; I will now go spelunking down inside it for a while. Wish me luck! > (-;Yes, rails 2.3 app is just an environment to custom matchers spec''ing/development. You can clone the git repo and just `rake spec` to see my issues... Those matchers (spec/lib/custom_ui_matchers/*) will be used in my real project tho. But I still have minor issues which are listed in Open questions section. Comments/remarks on the specs/code/etc are welcome! Good luck!
Yury Kotlyarov wrote:> Phlip wrote: >> Yury Kotlyarov wrote: >> >>>>>>> http://github.com/yura/howto-rspec-custom-matchers/ >> >>> The project aims to encourage feedback on the best practices of >>> creating custom expectation matchers and specs for them. >>> >>> Does it make sense? >> >> That just says it''s a "project". >> >> One git clone later... It is a Rails 2.3.0 website! >> >> TX; I will now go spelunking down inside it for a while. Wish me luck! >> (-; > > Yes, rails 2.3 app is just an environment to custom matchers > spec''ing/development. You can clone the git repo and just `rake spec` to > see my issues...Special-needs programmer that I am, I declined to obtain the unreleased 2.3.0 of Rails. I tweaked environment.rb back to 2.2.2. That lead to a curious issue that an RSpec maintainer might understand: ----8<----------------------------------------------------- $ rake spec (in /home/phlip/projects/howto-rspec-custom-matchers) /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'': no such file to load -- application (MissingSourceFile) from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:155:in `require'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:262:in `require_or_load'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:221:in `depend_on'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/dependencies.rb:133:in `require_dependency'' from /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:18:in `define_dispatcher_callbacks'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/callbacks.rb:182:in `call'' from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.2.2/lib/active_support/callbacks.rb:182:in `evaluate_method'' ... 19 levels... from /home/phlip/projects/howto-rspec-custom-matchers/vendor/plugins/rspec/lib/spec/runner/example_group_runner.rb:14:in `load_files'' from /home/phlip/projects/howto-rspec-custom-matchers/vendor/plugins/rspec/lib/spec/runner/options.rb:84:in `run_examples'' from /home/phlip/projects/howto-rspec-custom-matchers/vendor/plugins/rspec/lib/spec/runner/command_line.rb:9:in `run'' from /home/phlip/projects/howto-rspec-custom-matchers/vendor/plugins/rspec/bin/spec:4 ----8<----------------------------------------------------- Apologies for the ugly unformattable stack trace, but I don''t know which lines are important. I fixed the "missing application.rb" error via brute force: cp `find . -name application.rb`. With a copy of application.rb in the root folder, ''rake spec'' now works, and I can see some "Not Yet Implemented" issues...> Those matchers (spec/lib/custom_ui_matchers/*) will be used in my real > project tho. But I still have minor issues which are listed in Open > questions section. Comments/remarks on the specs/code/etc are welcome!Well, the rake spec generally passed, so someone else will have to tell you whatever it was you did wrong! (-: -- Phlip http://flea.sourceforge.net/PiglegToo_1.html
> This looks pretty cool. I wonder if you''d have any interest in making > this a bit more rspec-friendly? Something like an option to run it > like this:Here''s the spec. The sauce is below my signature. it ''should have a user form with the first name'' do render ''/users/new'' response.body.should be_xml_with do xpath :form, :action => ''/users'' do xpath :fieldset do xpath :''legend[ contains(., "Personal Information") ]'' and xpath :''label[ contains(., "First name") ]'' and xpath :input, :type => ''text'', :name => ''user[first_name]'' end end end end Now, two issues. Firstly, what is the point of writing verbiage, designed for review by the customer team, if they should not be expected to understand hardcore engineering gibberish beginning with "body.should be_xml_with do"? A sentence that is only partly English does more harm than good! Secondly, when an xpath() fails, it prepares an elaborate and detailed analysis of the entire situation, packs this into a flunk(), and raises it in a Test::Unit::AssertionFailedError. Then RSpec then throws all that stuff away, and provides an incorrect stack trace to an internal error. Switching my ''user[first_name]'' to ''user[first_nome]'' provides this: NoMethodError in ''/users/new should have xpathic tags'' You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.first ./spec/views/users/new.html.erb_spec.rb:50: So if I were to rescue my own AssertionFailedError, and pack it into a failure_message, wouldn''t that effort be redundant? -- Phlip require ''assert2/xpath'' Spec::Runner.configure do |c| c.include Test::Unit::Assertions end # TODO blog this class BeXmlWith def initialize(scope, &block) @scope, @block = scope, block end def matches?(stwing, &block) waz_xdoc = @xdoc @block = block if block @scope.assert_xhtml stwing return (block || @block || proc{}).call ensure @xdoc = waz_xdoc end def failure_message "yack yack yack" end def negative_failure_message "yack yack yack" end end def be_xml_with(&block) BeXmlWith.new(self, &block) end
On Mon, Feb 16, 2009 at 9:36 AM, Phlip <phlip2005 at gmail.com> wrote:>> This looks pretty cool. I wonder if you''d have any interest in making >> this a bit more rspec-friendly? Something like an option to run it >> like this: > > Here''s the spec. The sauce is below my signature. > > it ''should have a user form with the first name'' do > render ''/users/new'' > response.body.should be_xml_with do > xpath :form, :action => ''/users'' do > xpath :fieldset do > xpath :''legend[ contains(., "Personal Information") ]'' and > xpath :''label[ contains(., "First name") ]'' and > xpath :input, :type => ''text'', :name => ''user[first_name]'' > end > end > end > end > > Now, two issues. Firstly, what is the point of writing verbiage, designed > for review by the customer team, if they should not be expected to > understand hardcore engineering gibberish beginning with "body.should > be_xml_with do"? A sentence that is only partly English does more harm than > good!When RSpec is used as customer facing, they see the docstrings (strings passed to describe() and it()), not the internal code. That''s for developers.> Secondly, when an xpath() fails, it prepares an elaborate and detailed > analysis of the entire situation, packs this into a flunk(), and raises it > in a Test::Unit::AssertionFailedError. > > Then RSpec then throws all that stuff away, and provides an incorrect stack > trace to an internal error. Switching my ''user[first_name]'' to > ''user[first_nome]'' provides this: > > NoMethodError in ''/users/new should have xpathic tags'' > You have a nil object when you didn''t expect it! > You might have expected an instance of Array. > The error occurred while evaluating nil.first > ./spec/views/users/new.html.erb_spec.rb:50: > > So if I were to rescue my own AssertionFailedError, and pack it into a > failure_message, wouldn''t that effort be redundant?Take a look at http://github.com/dchelimsky/rspec/blob/f6c75b1417d9178d4dcaaf9e892e23474d340ff6/lib/spec/matchers/wrap_expectation.rb, I think it''ll solve this problem. HTH, David> > -- > Phlip > > require ''assert2/xpath'' > > Spec::Runner.configure do |c| > c.include Test::Unit::Assertions > end # TODO blog this > > class BeXmlWith > > def initialize(scope, &block) > @scope, @block = scope, block > end > > def matches?(stwing, &block) > waz_xdoc = @xdoc > @block = block if block > @scope.assert_xhtml stwing > return (block || @block || proc{}).call > ensure > @xdoc = waz_xdoc > end > > def failure_message > "yack yack yack" > end > > def negative_failure_message > "yack yack yack" > end > end > > def be_xml_with(&block) > BeXmlWith.new(self, &block) > end > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
David Chelimsky wrote:> When RSpec is used as customer facing, they see the docstrings > (strings passed to describe() and it()), not the internal code. That''s > for developers.Then why the .should stuff? I''m a developer - technically - and I never needed it! But enough sophistry: Back to business...> Take a look at http://github.com/dchelimsky/rspec/blob/f6c75b1417d9178d4dcaaf9e892e23474d340ff6/lib/spec/matchers/wrap_expectation.rb, > I think it''ll solve this problem.This gives the same issue: class BeXmlWith def matches?(stwing, &block) waz_xdoc = @xdoc @scope.wrap_expectation self do @scope.assert_xhtml stwing return (block || @block || proc{}).call end ensure @xdoc = waz_xdoc end attr_accessor :failure_message The same error message for a stray nil: 1) ''/users/new should have xpathic tags'' FAILED You have a nil object when you didn''t expect it! You might have expected an instance of Array. The error occurred while evaluating nil.first ./spec/views/users/new.html.erb_spec.rb:50: line 50 is just this one: response.body.should be_xml_with do and yes the response.body is populated... -- Phlip
> The same error message for a stray nil:This attempt, calling simple_matcher directly, gives nearly the same nil: def be_xml_with_(&block) waz_xdoc = @xdoc simple_matcher ''yo'' do |given, matcher| wrap_expectation matcher do assert_xhtml given # this works block.call # crashes with a nil.first error! end end ensure @xdoc = waz_xdoc end it ''should have xpathic tags'' do render ''/users/new'' response.body.should be_xml_with{ # error points to this line xpath :form, :action => ''/users'' So why no stack trace so I can diagnose this?
On Mon, Feb 16, 2009 at 8:21 PM, Phlip <phlip2005 at gmail.com> wrote:> David Chelimsky wrote: > >> When RSpec is used as customer facing, they see the docstrings >> (strings passed to describe() and it()), not the internal code. That''s >> for developers. > > Then why the .should stuff? I''m a developer - technically - and I never > needed it!http://dannorth.net/introducing-bdd> > But enough sophistry: Back to business... > >> Take a look at >> http://github.com/dchelimsky/rspec/blob/f6c75b1417d9178d4dcaaf9e892e23474d340ff6/lib/spec/matchers/wrap_expectation.rb, >> I think it''ll solve this problem. > > This gives the same issue: > > class BeXmlWith > > def matches?(stwing, &block) > waz_xdoc = @xdoc > > @scope.wrap_expectation self do > @scope.assert_xhtml stwing > return (block || @block || proc{}).call > end > ensure > @xdoc = waz_xdoc > end > > attr_accessor :failure_message > > The same error message for a stray nil: > > > 1) > ''/users/new should have xpathic tags'' FAILED > You have a nil object when you didn''t expect it! > You might have expected an instance of Array. > The error occurred while evaluating nil.first > ./spec/views/users/new.html.erb_spec.rb:50: > > line 50 is just this one: > > response.body.should be_xml_with doThat''s the line you want to look at to know which example is failing. To see the full backtrace, use the --backtrace (-b) option. To learn about the various rspec options, use the --help (-h) option.> > and yes the response.body is populated...> > -- > Phlip > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >