This is pretty much the same as last time around, if you recall. Thanks to Wilson for converting to the new form. I''ve added a few lines. Basically, it iterates over your model associations and does two things. - First, just try to call the association. Usually fixes speeling erors or other such silliness. - Second, try to find a record with an :include on the association. This actually hits the DB and will tell you if you have lingering associations on deleted models. Page.find(:first, :include => :user) (Note: I usually feel that testing associations is really testing the framework, and such code belongs in the framework itself. Also, this won''t check if you removed some associations. And it won''t check for polymorphs either.) Put this somewhere handy and require it into spec_helper. ======================================= module ActiveRecordMatchers class HaveValidAssociations def matches?(model) @failed_association = nil @model_class = model.class model.class.reflect_on_all_associations.each do |assoc| begin model.send(assoc.name, true) model.class.send(''find'', :first, :include => assoc.name) rescue ActiveRecord::EagerLoadPolymorphicError # nothing. Can''t find :include a polymorph. This requires a better test. rescue => err @failed_association = "#{assoc.name} // #{err}" end end !@failed_association end def failure_message "invalid association \"#{@failed_association}\" on #{@model_class}" end end def have_valid_associations HaveValidAssociations.new end end ======================================= Put this in your model spec. context "A new Page" do include ActiveRecordMatchers specify "should have valid associations" do object = Page.new object.should have_valid_associations end end ======================================= court3nay http://blog.caboo.se
aslak hellesoy
2007-Mar-29 09:18 UTC
[rspec-users] a better "should have valid associations"
I really like it. Good to see custom matchers for RSpec are being put to use too. Does anyone think it would be a good idea to add this to spec:rails? Aslak On 3/29/07, Courtenay <court3nay at gmail.com> wrote:> This is pretty much the same as last time around, if you recall. > > Thanks to Wilson for converting to the new form. I''ve added a few > lines. Basically, it iterates over your model associations and does > two things. > > - First, just try to call the association. Usually fixes speeling > erors or other such silliness. > > - Second, try to find a record with an :include on the association. > This actually hits the DB and will tell you if you have lingering > associations on deleted models. Page.find(:first, :include => :user) > > (Note: I usually feel that testing associations is really testing the > framework, and such code belongs in the framework itself. Also, this > won''t check if you removed some associations. And it won''t check for > polymorphs either.) > > Put this somewhere handy and require it into spec_helper. > > =======================================> > module ActiveRecordMatchers > class HaveValidAssociations > def matches?(model) > @failed_association = nil > @model_class = model.class > > model.class.reflect_on_all_associations.each do |assoc| > begin > model.send(assoc.name, true) > model.class.send(''find'', :first, :include => assoc.name) > rescue ActiveRecord::EagerLoadPolymorphicError > # nothing. Can''t find :include a polymorph. This requires a > better test. > rescue => err > @failed_association = "#{assoc.name} // #{err}" > end > end > !@failed_association > end > > def failure_message > "invalid association \"#{@failed_association}\" on #{@model_class}" > end > end > > def have_valid_associations > HaveValidAssociations.new > end > end > > =======================================> > Put this in your model spec. > > context "A new Page" do > include ActiveRecordMatchers > > specify "should have valid associations" do > object = Page.new > object.should have_valid_associations > end > end > > =======================================> > > court3nay > http://blog.caboo.se > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Ashley Moran
2007-Mar-29 09:38 UTC
[rspec-users] a better "should have valid associations"
On 29 Mar 2007, at 09:18, Courtenay wrote:> Note: I usually feel that testing associations is really testing the > framework, and such code belongs in the framework itself.All the fancy details that load and save are part of the framework, but you still have to write has_whatever in your model class. My test-code ratio for models is 3.8:1, almost entirely due to copy-and- past coding to verify the associations. I''d love a really expressive way of testing associations like "Car.should have_many(:wheels)" or "Bull.should have_one(:udder)" or whatever. But looking at my own code it would be hard to factor out a one-size-fits-all expectation, especially through associations. Ashley
Craig Demyanovich
2007-Mar-29 13:03 UTC
[rspec-users] a better "should have valid associations"
On Mar 29, 2007, at 5:38 AM, Ashley Moran wrote:> > On 29 Mar 2007, at 09:18, Courtenay wrote: > >> Note: I usually feel that testing associations is really testing the >> framework, and such code belongs in the framework itself. > > All the fancy details that load and save are part of the framework, > but you still have to write has_whatever in your model class. My > test-code ratio for models is 3.8:1, almost entirely due to copy-and- > past coding to verify the associations. I''d love a really expressive > way of testing associations like "Car.should have_many(:wheels)" or > "Bull.should have_one(:udder)" or whatever. But looking at my own > code it would be hard to factor out a one-size-fits-all expectation, > especially through associations.Here''s how I''m currently specifying my associations: context "All campaigns" do specify "may have many funds" do association = Campaign.reflect_on_association(:funds) association.macro.should == :has_many association.class_name.should == ''Fund'' association.options.should == { :foreign_key => ''FK_Campaign'' } end end context "All funds" do specify "may belong to a campaign" do association = Fund.reflect_on_association(:campaign) association.macro.should == :belongs_to association.class_name.should == ''Campaign'' association.options.should == { :foreign_key => ''FK_Campaign'' } end end Doing more than this feels like doing too much. However, I''m still a bit of a beginner when it comes to Rails. Am I specifying too little? Am I missing something? Regards, Craig
Ashley Moran
2007-Mar-29 13:37 UTC
[rspec-users] a better "should have valid associations"
On 29 Mar 2007, at 14:03, Craig Demyanovich wrote:> Doing more than this feels like doing too much. However, I''m still a > bit of a beginner when it comes to Rails. Am I specifying too little? > Am I missing something?That''s a lot more concise than my version! I''m sure there are people with more informed opinions, but to me your solution looks like it depends a lot on the Rails implementation, so the specs would be useless if you wanted to switch (or could switch) to Og, say. My specs look like this: context "A SiteVariable (associations)" do setup do # fixtures here, then make a variable... @variable = SiteVariable.new(:name => "variable") end specify "should belong to SiteVariableCategory" do @variable.site_variable_type = @type @variable.should respond_to(:site_variable_category) @variable.should respond_to(:site_variable_category=) @variable.site_variable_category = @category @variable.save! variable = SiteVariable.find(@variable.id) variable.site_variable_category.should == @category end specify "should have many SiteValues" do @variable.site_variable_category = @category @variable.site_variable_type = @type site_value_1 = SiteStringValue.new(:string_value => "value_1", :site => @site) site_value_2 = SiteStringValue.new(:string_value => "value_2", :site => @site) @variable.should respond_to(:site_values) @variable.site_values.should respond_to(:<<) @variable.site_values << site_value_1 @variable.site_values << site_value_2 @variable.save.should == true variable_reloaded = SiteVariable.find(@variable.id) variable_reloaded.site_values.sort { |a, b| a.string_value <=> b.string_value }.should == [ site_value_1, site_value_2 ] end end It''s ugly and long winded, but it tests the actual behaviour. I''m sure somewhere between the two approaches there''s an ideal solution. Ashley
Bryan Helmkamp
2007-Mar-29 14:22 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, Courtenay <court3nay at gmail.com> wrote:> Thanks to Wilson for converting to the new form. I''ve added a few > lines.Actually, I converted this to the matcher syntax. Wilson and I are using it on a project we are working on together. While have_valid_associations is useful as a safety net in places where you are otherwise uncovered, I now strongly prefer enumerating the associations that should exist in the spec. To do that, we use the following code: ========================================= class HaveAssociation def initialize(association_name) @association_name = association_name end def matches?(model) @model_class = model.class success = true model.send(@association_name.to_sym, true) rescue success = false success end def failure_message "invalid or nonexistent association \"#{@association_name}\" on #{@model_class}" end end def have_association(association_name) HaveAssociation.new(association_name) end ========================================= And then in the model spec (we include ActiveRecordMatchers in the context for all model specs): context "A car" do setup do @car = Car.new end specify "should have valid associations" do @car.should have_association(:owner) @car.should have_association(:insurance) end end Now we''re covered in the case that an association is accidentally removed. The "should have valid associations" specification can get a big long and ugly on more complex classes, so we often use this syntax: context "A car" do setup do @car = Car.new end %w[owner insurance driver passengers engine].each do |assoc| specify "should have valid #{assoc} association" do @car.should have_association(assoc) end end This has the added bonus of producing much better specdoc: A car - should have valid owner association - should have valid insurance association - should have valid driver association - should have valid passengers association - should have valid engine association -Bryan
Craig Demyanovich
2007-Mar-29 14:45 UTC
[rspec-users] a better "should have valid associations"
On Mar 29, 2007, at 10:22 AM, Bryan Helmkamp wrote:> On 3/29/07, Courtenay <court3nay at gmail.com> wrote: >> Thanks to Wilson for converting to the new form. I''ve added a few >> lines. > > Actually, I converted this to the matcher syntax. Wilson and I are > using it on a project we are working on together. > > While have_valid_associations is useful as a safety net in places > where you are otherwise uncovered, I now strongly prefer enumerating > the associations that should exist in the spec. To do that, we use the > following code: > > =========================================> > class HaveAssociation > def initialize(association_name) > @association_name = association_name > end > > def matches?(model) > @model_class = model.class > success = true > model.send(@association_name.to_sym, true) rescue success = > false > success > end > > def failure_message > "invalid or nonexistent association \"#{@association_name}\" on > #{@model_class}" > end > end > > def have_association(association_name) > HaveAssociation.new(association_name) > end > > =========================================> > And then in the model spec (we include ActiveRecordMatchers in the > context for all model specs): > > context "A car" do > setup do > @car = Car.new > end > > specify "should have valid associations" do > @car.should have_association(:owner) > @car.should have_association(:insurance) > end > end > > Now we''re covered in the case that an association is accidentally > removed. The "should have valid associations" specification can get a > big long and ugly on more complex classes, so we often use this > syntax: > > context "A car" do > setup do > @car = Car.new > end > > %w[owner insurance driver passengers engine].each do |assoc| > specify "should have valid #{assoc} association" do > @car.should have_association(assoc) > end > end > > This has the added bonus of producing much better specdoc: > > A car > - should have valid owner association > - should have valid insurance association > - should have valid driver association > - should have valid passengers association > - should have valid engine association > > -BryanNice idea, Bryan. It doesn''t go far enough for me, though: it verifies only the name of the association. I want to verify that I''ve specified the correct macro (e.g., :has_many instead of :has_one), class and foreign key. Part of why I want this is because I''m working with a legacy database that doesn''t follow the Rails conventions at all. In addition, though, checking all of the association attributes increases my confidence that I''ll notice if something about the association changes or if I make a mistake defining it, such as using :has_one instead of :has_many. For these reasons, I''m doing what I posted earlier in this thread. Thoughts? Craig
David Chelimsky
2007-Mar-29 15:05 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, Craig Demyanovich <cdemyanovich at gmail.com> wrote:> On Mar 29, 2007, at 10:22 AM, Bryan Helmkamp wrote: > > > On 3/29/07, Courtenay <court3nay at gmail.com> wrote: > >> Thanks to Wilson for converting to the new form. I''ve added a few > >> lines. > > > > Actually, I converted this to the matcher syntax. Wilson and I are > > using it on a project we are working on together. > > > > While have_valid_associations is useful as a safety net in places > > where you are otherwise uncovered, I now strongly prefer enumerating > > the associations that should exist in the spec. To do that, we use the > > following code: > > > > =========================================> > > > class HaveAssociation > > def initialize(association_name) > > @association_name = association_name > > end > > > > def matches?(model) > > @model_class = model.class > > success = true > > model.send(@association_name.to_sym, true) rescue success > > false > > success > > end > > > > def failure_message > > "invalid or nonexistent association \"#{@association_name}\" on > > #{@model_class}" > > end > > end > > > > def have_association(association_name) > > HaveAssociation.new(association_name) > > end > > > > =========================================> > > > And then in the model spec (we include ActiveRecordMatchers in the > > context for all model specs): > > > > context "A car" do > > setup do > > @car = Car.new > > end > > > > specify "should have valid associations" do > > @car.should have_association(:owner) > > @car.should have_association(:insurance) > > end > > end > > > > Now we''re covered in the case that an association is accidentally > > removed. The "should have valid associations" specification can get a > > big long and ugly on more complex classes, so we often use this > > syntax: > > > > context "A car" do > > setup do > > @car = Car.new > > end > > > > %w[owner insurance driver passengers engine].each do |assoc| > > specify "should have valid #{assoc} association" do > > @car.should have_association(assoc) > > end > > end > > > > This has the added bonus of producing much better specdoc: > > > > A car > > - should have valid owner association > > - should have valid insurance association > > - should have valid driver association > > - should have valid passengers association > > - should have valid engine association > > > > -Bryan > > Nice idea, Bryan. It doesn''t go far enough for me, though: it > verifies only the name of the association. I want to verify that I''ve > specified the correct macro (e.g., :has_many instead of :has_one), > class and foreign key. Part of why I want this is because I''m working > with a legacy database that doesn''t follow the Rails conventions at > all. In addition, though, checking all of the association attributes > increases my confidence that I''ll notice if something about the > association changes or if I make a mistake defining it, such as > using :has_one instead of :has_many. For these reasons, I''m doing > what I posted earlier in this thread. Thoughts?How about this? project.should belong_to(:manager) manager.should have_many(:projects) etc This would involve more matchers, but could be implemented in the same fashion as have_association is above. David> > Craig > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Matthijs Langenberg
2007-Mar-29 15:09 UTC
[rspec-users] a better "should have valid associations"
Would that be possible to implement? Looks much cleaner then solutions I''ve been using in RSpec or Test::Unit. On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote:> On 3/29/07, Craig Demyanovich <cdemyanovich at gmail.com> wrote: > > On Mar 29, 2007, at 10:22 AM, Bryan Helmkamp wrote: > > > > > On 3/29/07, Courtenay <court3nay at gmail.com> wrote: > > >> Thanks to Wilson for converting to the new form. I''ve added a few > > >> lines. > > > > > > Actually, I converted this to the matcher syntax. Wilson and I are > > > using it on a project we are working on together. > > > > > > While have_valid_associations is useful as a safety net in places > > > where you are otherwise uncovered, I now strongly prefer enumerating > > > the associations that should exist in the spec. To do that, we use the > > > following code: > > > > > > =========================================> > > > > > class HaveAssociation > > > def initialize(association_name) > > > @association_name = association_name > > > end > > > > > > def matches?(model) > > > @model_class = model.class > > > success = true > > > model.send(@association_name.to_sym, true) rescue success > > > false > > > success > > > end > > > > > > def failure_message > > > "invalid or nonexistent association \"#{@association_name}\" on > > > #{@model_class}" > > > end > > > end > > > > > > def have_association(association_name) > > > HaveAssociation.new(association_name) > > > end > > > > > > =========================================> > > > > > And then in the model spec (we include ActiveRecordMatchers in the > > > context for all model specs): > > > > > > context "A car" do > > > setup do > > > @car = Car.new > > > end > > > > > > specify "should have valid associations" do > > > @car.should have_association(:owner) > > > @car.should have_association(:insurance) > > > end > > > end > > > > > > Now we''re covered in the case that an association is accidentally > > > removed. The "should have valid associations" specification can get a > > > big long and ugly on more complex classes, so we often use this > > > syntax: > > > > > > context "A car" do > > > setup do > > > @car = Car.new > > > end > > > > > > %w[owner insurance driver passengers engine].each do |assoc| > > > specify "should have valid #{assoc} association" do > > > @car.should have_association(assoc) > > > end > > > end > > > > > > This has the added bonus of producing much better specdoc: > > > > > > A car > > > - should have valid owner association > > > - should have valid insurance association > > > - should have valid driver association > > > - should have valid passengers association > > > - should have valid engine association > > > > > > -Bryan > > > > Nice idea, Bryan. It doesn''t go far enough for me, though: it > > verifies only the name of the association. I want to verify that I''ve > > specified the correct macro (e.g., :has_many instead of :has_one), > > class and foreign key. Part of why I want this is because I''m working > > with a legacy database that doesn''t follow the Rails conventions at > > all. In addition, though, checking all of the association attributes > > increases my confidence that I''ll notice if something about the > > association changes or if I make a mistake defining it, such as > > using :has_one instead of :has_many. For these reasons, I''m doing > > what I posted earlier in this thread. Thoughts? > > How about this? > > project.should belong_to(:manager) > manager.should have_many(:projects) > > etc > > This would involve more matchers, but could be implemented in the same > fashion as have_association is above. > > David > > > > Craig > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Craig Demyanovich
2007-Mar-29 15:30 UTC
[rspec-users] a better "should have valid associations"
On Mar 29, 2007, at 11:05 AM, David Chelimsky wrote:> On 3/29/07, Craig Demyanovich <cdemyanovich at gmail.com> wrote: >> On Mar 29, 2007, at 10:22 AM, Bryan Helmkamp wrote: >> >>> On 3/29/07, Courtenay <court3nay at gmail.com> wrote: >>>> Thanks to Wilson for converting to the new form. I''ve added a few >>>> lines. >>> >>> Actually, I converted this to the matcher syntax. Wilson and I are >>> using it on a project we are working on together. >>> >>> While have_valid_associations is useful as a safety net in places >>> where you are otherwise uncovered, I now strongly prefer enumerating >>> the associations that should exist in the spec. To do that, we >>> use the >>> following code: >>> >>> =========================================>>> >>> class HaveAssociation >>> def initialize(association_name) >>> @association_name = association_name >>> end >>> >>> def matches?(model) >>> @model_class = model.class >>> success = true >>> model.send(@association_name.to_sym, true) rescue success >>> false >>> success >>> end >>> >>> def failure_message >>> "invalid or nonexistent association \"#{@association_name} >>> \" on >>> #{@model_class}" >>> end >>> end >>> >>> def have_association(association_name) >>> HaveAssociation.new(association_name) >>> end >>> >>> =========================================>>> >>> And then in the model spec (we include ActiveRecordMatchers in the >>> context for all model specs): >>> >>> context "A car" do >>> setup do >>> @car = Car.new >>> end >>> >>> specify "should have valid associations" do >>> @car.should have_association(:owner) >>> @car.should have_association(:insurance) >>> end >>> end >>> >>> Now we''re covered in the case that an association is accidentally >>> removed. The "should have valid associations" specification can >>> get a >>> big long and ugly on more complex classes, so we often use this >>> syntax: >>> >>> context "A car" do >>> setup do >>> @car = Car.new >>> end >>> >>> %w[owner insurance driver passengers engine].each do |assoc| >>> specify "should have valid #{assoc} association" do >>> @car.should have_association(assoc) >>> end >>> end >>> >>> This has the added bonus of producing much better specdoc: >>> >>> A car >>> - should have valid owner association >>> - should have valid insurance association >>> - should have valid driver association >>> - should have valid passengers association >>> - should have valid engine association >>> >>> -Bryan >> >> Nice idea, Bryan. It doesn''t go far enough for me, though: it >> verifies only the name of the association. I want to verify that I''ve >> specified the correct macro (e.g., :has_many instead of :has_one), >> class and foreign key. Part of why I want this is because I''m working >> with a legacy database that doesn''t follow the Rails conventions at >> all. In addition, though, checking all of the association attributes >> increases my confidence that I''ll notice if something about the >> association changes or if I make a mistake defining it, such as >> using :has_one instead of :has_many. For these reasons, I''m doing >> what I posted earlier in this thread. Thoughts? > > How about this? > > project.should belong_to(:manager) > manager.should have_many(:projects) > > etc > > This would involve more matchers, but could be implemented in the same > fashion as have_association is above.That looks pretty good, David. In fact, it''s probably just right for apps that use a database that follows the Rails conventions. However, does anyone have any ideas for how we could specify the class and foreign key? I feel that I need to specify those as well since my database is quite unconventional according to Rails. Change may be in its future, but it''s not safe just yet. Thanks, Craig
Josh Knowles
2007-Mar-29 15:35 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote:> > > > How about this? > > project.should belong_to(:manager) > manager.should have_many(:projects) > > etc > > This would involve more matchers, but could be implemented in the same > fashion as have_association is above.I''ve implenented the first pass at the following rails matchers: should belong_to(association) should have_many(association) should validate_confirmation_of(attribute) should validate_format_of(attribute, valid => [], invalid => []) should validate_lendth_of(attribute, range) should validate_presence_of(attribute) should validate_uniqueness_of(attribute) Plugin available here: http://svn.integrumtech.com/public/plugins/rspec_on_rails_matchers/ I haven''t had a chance to get the README done, or any rdoc, but there are specs for the majority of the matchers. Comments / Suggestions Welcome! Josh -- Josh Knowles joshknowles at gmail.com http://joshknowles.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070329/3da6ea13/attachment.html
David Chelimsky
2007-Mar-29 15:44 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, Josh Knowles <joshknowles at gmail.com> wrote:> > > On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > > > How about this? > > > > project.should belong_to(:manager) > > manager.should have_many(:projects) > > > > etc > > > > This would involve more matchers, but could be implemented in the same > > fashion as have_association is above. > > > I''ve implenented the first pass at the following rails matchers: > > should belong_to(association) > should have_many(association) > should validate_confirmation_of(attribute) > should validate_format_of(attribute, valid => [], invalid => []) > should validate_lendth_of(attribute, range) > should validate_presence_of(attribute) > should validate_uniqueness_of(attribute) > > Plugin available here: > http://svn.integrumtech.com/public/plugins/rspec_on_rails_matchers/ > > I haven''t had a chance to get the README done, or any rdoc, but there are > specs for the majority of the matchers. > > Comments / Suggestions Welcome!AWESOME! I''m so psyched to see a plugin emerging for this. Looks like have_many and belong_to don''t really specify the specific type of association, so you could get false positives. Also, it probably needs a have_one and have_and_belong_to_many matchers is well to round it out, no? Cheers, David> > Josh > > > > > -- > Josh Knowles > joshknowles at gmail.com > http://joshknowles.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Josh Knowles
2007-Mar-29 15:49 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote:> AWESOME! I''m so psyched to see a plugin emerging for this. > > Looks like have_many and belong_to don''t really specify the specific > type of association, so you could get false positives. Also, it > probably needs a have_one and have_and_belong_to_many matchers is well > to round it out, no?Yes this is definitely still a work in progress, and I wasn''t quite ready to release, but figured since folks were talking about this now I''d throw it out there and get feedback earlier rather then later. Josh -- Josh Knowles joshknowles at gmail.com http://joshknowles.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070329/933c7801/attachment.html
aslak hellesoy
2007-Mar-29 16:02 UTC
[rspec-users] a better "should have valid associations"
On 3/29/07, Josh Knowles <joshknowles at gmail.com> wrote:> > > On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > AWESOME! I''m so psyched to see a plugin emerging for this. > >I second that.> > Looks like have_many and belong_to don''t really specify the specific > > type of association, so you could get false positives. Also, it > > probably needs a have_one and have_and_belong_to_many matchers is well > > to round it out, no? > > > Yes this is definitely still a work in progress, and I wasn''t quite ready to > release, but figured since folks were talking about this now I''d throw it > out there and get feedback earlier rather then later. >Now that the rspec plugin mechanism seems to be working nicely, we don''t have to include lots of stuff in the Spec::Rails codebase. However, we should make sure the RSpec website includes a link to valuable plugins like this one. Aslak> Josh > > > > > -- > Josh Knowles > joshknowles at gmail.com > http://joshknowles.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Brandon Keepers
2007-Mar-30 18:09 UTC
[rspec-users] a better "should have valid associations"
I need to keep up with this list more. I hadn''t read the posts from yesterday and implemented a matcher this morning based off of Craig''s post to the Grand Rapids Ruby group list[1]. module Spec module Rails module Matchers class HaveAssociation #:nodoc: def initialize(type, name, options = {}) @type = type @name = name @options = options @class_name = options[:class_name] || @name.to_s.singularize.camelize end def matches?(model) @model = model @association = model.reflect_on_association(@name) @association && @association.macro == @type && @association.class_name == @class_name && @association.options == @options end def failure_message "expected #{model.inspect} to have a #{type} association called ''#{name}'', but got #{association.inspect}" end def description "have a #{type} association called :#{name}" end private attr_reader :type, :name, :model, :association end def have_association(type, name, options = {}) HaveAssociation.new(type, name, options) end end end end and in my spec: context "A comment" do specify "should belong to a message" do Comment.should have_association (:belongs_to, :message, :class_name => ''Post'', :foreign_key => ''custom_foreign_key'') end end The only thing I don''t like about this approach (and ones similar) is that it only checks the declaration. While that is important, I also think specs need to check that the declaration actually works (foreign key exists in database, model exists, etc.). Brandon [1] http://lists.gr-ruby.org/pipermail/discuss-gr-ruby.org/2007-March/ 000568.html On Mar 29, 2007, at 11:35 AM, Josh Knowles wrote:> > > On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > How about this? > > project.should belong_to(:manager) > manager.should have_many(:projects) > > etc > > This would involve more matchers, but could be implemented in the same > fashion as have_association is above. > > > I''ve implenented the first pass at the following rails matchers: > > should belong_to(association) > should have_many(association) > should validate_confirmation_of(attribute) > should validate_format_of(attribute, valid => [], invalid => []) > should validate_lendth_of(attribute, range) > should validate_presence_of(attribute) > should validate_uniqueness_of(attribute) > > Plugin available here: http://svn.integrumtech.com/public/plugins/ > rspec_on_rails_matchers/ > > I haven''t had a chance to get the README done, or any rdoc, but > there are specs for the majority of the matchers. > > Comments / Suggestions Welcome! > > Josh > > > > > -- > Josh Knowles > joshknowles at gmail.com > http://joshknowles.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users
On 3/30/07, Brandon Keepers <bkeepers at gmail.com> wrote:> > The only thing I don''t like about this approach (and ones similar) is > that it only checks the declaration. While that is important, I also > think specs need to check that the declaration actually works > (foreign key exists in database, model exists, etc.). >That''s what my original post does. Court3nay
Chad Humphries
2007-Mar-31 00:18 UTC
[rspec-users] a better "should have valid associations"
I''ve been working on building out standard expectation matchers for all the built-in validations in rails ala: setup do @user = User.new(valid_user_attributes) end specify do @user.should require_presence_of :first_name end specify do @user.should require_confirmation_of :password end The first version has a few of the validators, the next release coming shortly will finish out all the rest. -chad On 3/30/07, Courtenay <court3nay at gmail.com> wrote:> On 3/30/07, Brandon Keepers <bkeepers at gmail.com> wrote: > > > > The only thing I don''t like about this approach (and ones similar) is > > that it only checks the declaration. While that is important, I also > > think specs need to check that the declaration actually works > > (foreign key exists in database, model exists, etc.). > > > > That''s what my original post does. > > > Court3nay > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Chad Humphries
2007-Mar-31 00:21 UTC
[rspec-users] a better "should have valid associations"
josh, sweet, missed your earlier post, looks like we''ve both finished these out :) -chad On 3/29/07, Josh Knowles <joshknowles at gmail.com> wrote:> > > On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > > > > > How about this? > > > > project.should belong_to(:manager) > > manager.should have_many(:projects) > > > > etc > > > > This would involve more matchers, but could be implemented in the same > > fashion as have_association is above. > > > I''ve implenented the first pass at the following rails matchers: > > should belong_to(association) > should have_many(association) > should validate_confirmation_of(attribute) > should validate_format_of(attribute, valid => [], invalid => []) > should validate_lendth_of(attribute, range) > should validate_presence_of(attribute) > should validate_uniqueness_of(attribute) > > Plugin available here: > http://svn.integrumtech.com/public/plugins/rspec_on_rails_matchers/ > > I haven''t had a chance to get the README done, or any rdoc, but there are > specs for the majority of the matchers. > > Comments / Suggestions Welcome! > > Josh > > > > > -- > Josh Knowles > joshknowles at gmail.com > http://joshknowles.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
On 29-Mar-07, at 1:02 PM, aslak hellesoy wrote:> On 3/29/07, Josh Knowles <joshknowles at gmail.com> wrote: >> >> >> On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: >>> AWESOME! I''m so psyched to see a plugin emerging for this. >>> > > I second that.I''ll play devils-advocate.. what does all this have to do with specifying behaviour? From a specification point of view, do I care that there''s a valiadtor for a field? I don''t think so... I''m more concerned with what happens when I try to use a bad value for that field. That there''s a validator for it in the model is an implementation detail. That said, it''s great stuff for a plugin. Dave -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070331/7bf1c9a8/attachment.html
aslak hellesoy
2007-Mar-31 18:09 UTC
[rspec-users] a better "should have valid associations"
On 3/31/07, Dave Astels <dastels at daveastels.com> wrote:> > > On 29-Mar-07, at 1:02 PM, aslak hellesoy wrote: > > > On 3/29/07, Josh Knowles <joshknowles at gmail.com> wrote: > > > > > > > > > On 3/29/07, David Chelimsky <dchelimsky at gmail.com> wrote: > > > AWESOME! I''m so psyched to see a plugin emerging for this. > > > > > > > > I second that. > I''ll play devils-advocate.. what does all this have to do with specifying > behaviour? >Probably not much, but can''t we say that about most of RSpec''s built-in matchers? Like for example: foo.should match(/bar/) What does that have to do with behaviour?> From a specification point of view, do I care that there''s a valiadtor for a > field? I don''t think so... I''m more concerned with what happens when I try > to use a bad value for that field. That there''s a validator for it in the > model is an implementation detail. > > That said, it''s great stuff for a plugin. >I''ve been thinking - would it make sense to modify the rspec_resource generator to generate specs that use the matchers provided by Josh''s plugin? It would be possible to infer from foreign key fields passed as arguments to the generator (name:string project_id:integer) etc. Aslak> Dave > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
David Chelimsky
2007-Mar-31 20:44 UTC
[rspec-users] a better "should have valid associations"
On 3/31/07, aslak hellesoy <aslak.hellesoy at gmail.com> wrote:> On 3/31/07, Dave Astels <dastels at daveastels.com> wrote: > > I''ll play devils-advocate.. what does all this have to do with specifying > > behaviour? > > Probably not much, but can''t we say that about most of RSpec''s > built-in matchers? Like for example: > > foo.should match(/bar/) > > What does that have to do with behaviour?I think it gets too easy to say "if we''re checking state it''s not about behaviour" but I think that''s wrong. Some objects answer questions - and that IS their behaviour. If an object answers the same question in two different ways based on what you''ve done (or not done) before you ask the question, then that is behaviour. I think the distinction here is that we''re really describing an object''s structure, not its behaviour, when we say: pet_shop.should have_many(:pets) This is an interesting dilemma that were forced to negotiate our way through because Rails breaks what have long been considered good Object Oriented principles like "favor delegation over inheritance". It is adherence to that principle, in my view, that makes Spring the hands down winner over Struts in the java space. Well, there are other reasons as well. But there''s a counter argument to all this, which is pragmatism. I can express a lot of implied behaviour by saying: describe User do it "should require email" do User.new.should validate_presence_of(:email) end end I think that has some value. The risk, of course, is that we''re now married to Rails and it would be hard to use a different framework without changing all of our examples. If that''s the fear, then you really shouldn''t be using Rails to begin with.> > > From a specification point of view, do I care that there''s a valiadtor for a > > field? I don''t think so... I''m more concerned with what happens when I try > > to use a bad value for that field. That there''s a validator for it in the > > model is an implementation detail. > > > > That said, it''s great stuff for a plugin. > > I''ve been thinking - would it make sense to modify the rspec_resource > generator to generate specs that use the matchers provided by Josh''s > plugin? It would be possible to infer from foreign key fields passed > as arguments to the generator (name:string project_id:integer) etc.My instinct is that I wouldn''t want the dependency from Spec::Rails to another plugin. If that''s the goal we should either ship the rspec_resource generator as a separate plugin or move Josh''s plugin into RSpec (w/ his permission, of course). Thoughts on that (especially from Josh)? David> > Aslak > > > Dave > > > > > > _______________________________________________ > > rspec-users mailing list > > rspec-users at rubyforge.org > > http://rubyforge.org/mailman/listinfo/rspec-users > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Josh Knowles
2007-Apr-01 23:42 UTC
[rspec-users] a better "should have valid associations"
On 3/31/07, David Chelimsky <dchelimsky at gmail.com> wrote:> My instinct is that I wouldn''t want the dependency from Spec::Rails to > another plugin. If that''s the goal we should either ship the > rspec_resource generator as a separate plugin or move Josh''s plugin > into RSpec (w/ his permission, of course). > > Thoughts on that (especially from Josh)?I''m all for moving this into rspec_on_rails. The only reason I released this originally as a plugin was honestly because the barrier to entry of getting the rspec dev environment up and running was to much. Dealing with old versions of webgen and not being able to use sqlite was to much frustration for an afternoon hack project. If there is enough interest I will gladly add the additional association matchers and submit everything as a patch. Josh -- Josh Knowles joshknowles at gmail.com http://joshknowles.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20070401/55df0688/attachment.html