diff --git a/test/unit/product_test.rb b/test/unit/product_test.rb index 7ce4821..a32c0b3 100644 --- a/test/unit/product_test.rb +++ b/test/unit/product_test.rb @@ -8,6 +8,14 @@ class ProductTest < ActiveSupport::TestCase @profile = fast_create(Enterprise) end + should 'return associated enterprise region' do + @profile.region = fast_create Region, :name => 'Salvador' + @profile.save! + p = fast_create(Product, :name => 'test product1', :product_category_id => @product_category.id, :enterprise_id => @profile.id) + + assert_equal @profile.region, p.region + end + should 'create product' do assert_difference Product, :count do p = Product.new(:name => 'test product1', :product_category => @product_category, :enterprise_id => @profile.id) diff --git a/vendor/plugins/nested_has_many_through/.gitignore b/vendor/plugins/nested_has_many_through/.gitignore new file mode 100644 index 0000000..57f3a0b --- /dev/null +++ b/vendor/plugins/nested_has_many_through/.gitignore @@ -0,0 +1,2 @@ +.garlic +doc/* diff --git a/vendor/plugins/nested_has_many_through/CHANGELOG b/vendor/plugins/nested_has_many_through/CHANGELOG new file mode 100644 index 0000000..2a62803 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/CHANGELOG @@ -0,0 +1,4 @@ +* spec'd and fixed some problems with using named_scope in edge + +* Initial commit + diff --git a/vendor/plugins/nested_has_many_through/MIT-LICENSE b/vendor/plugins/nested_has_many_through/MIT-LICENSE new file mode 100644 index 0000000..906139d --- /dev/null +++ b/vendor/plugins/nested_has_many_through/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008 Ian White - ian.w.white@gmail.com + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/vendor/plugins/nested_has_many_through/README.rdoc b/vendor/plugins/nested_has_many_through/README.rdoc new file mode 100755 index 0000000..03f01f6 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/README.rdoc @@ -0,0 +1,92 @@ +http://plugins.ardes.com > nested_has_many_through + += nested_has_many_through + +A fantastic patch/plugin has been floating around for a while: + +* http://dev.rubyonrails.org/ticket/6461 +* http://code.torchbox.com/svn/rails/plugins/nested_has_many_through + +obrie made the original ticket and Matt Westcott released the first version of +the plugin, under the MIT license. Many others have contributed, see the trac +ticket for details. + +Here is a refactored version (I didn't write the original), suitable for edge/2.0-stable +with a bunch of acceptance specs. I'm concentrating on plugin usage, once +it becomes stable, and well enough speced/understood, then it's time to pester +rails-core. + +== Why republish this on github? + +* The previous implementations are very poorly speced/tested, so it's pretty + hard to refactor and understand this complicated bit of sql-fu, especially + when you're aiming at a moving target (edge) +* the lastest patches don't apply on edge +* github - let's collab to make this better and get a patch accepted, fork away! + +== Help out + +I'm releasing 'early and often' in the hope that people will use it and find bugs/problems. +Report them at http://ianwhite.lighthouseapp.com, or fork and pull request, yada yada. + +== History + +Here's the original description: + + This plugin makes it possible to define has_many :through relationships that + go through other has_many :through relationships, possibly through an + arbitrarily deep hierarchy. This allows associations across any number of + tables to be constructed, without having to resort to find_by_sql (which isn't + a suitable solution if you need to do eager loading through :include as well). + +== Contributors + +* Matt Westcott +* terceiro +* shoe +* mhoroschun +* Ian White (http://github.com/ianwhite) +* Claudio (http://github.com/masterkain) + +Get in touch if you should be on this list + +== Show me the money! + +Here's some models from the specs: + + class Author < User + has_many :posts + has_many :categories, :through => :posts, :uniq => true + has_many :similar_posts, :through => :categories, :source => :posts + has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true + has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true + has_many :commenters, :through => :posts, :uniq => true + end + + class Post < ActiveRecord::Base + belongs_to :author + belongs_to :category + has_many :comments + has_many :commenters, :through => :comments, :source => :user, :uniq => true + end + +The first two has_manys of Author are plain vanilla, the last four are what this plugin enables + + # has_many through a has_many :through + has_many :similar_posts, :through => :categories, :source => :posts + + # doubly nested has_many :through + has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true + + # whoah! + has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true + + # has_many through a has_many :through in another model + has_many :commenters, :through => :posts, :uniq => true + +== What does it run on? + +Currently it's running on 2.0, 2.1, and 2.2 stable branches + +If you want to run the CI suite, then check out garlic_example.rb (The CI suite +is being cooked with garlic - git://github.com/ianwhite/garlic) diff --git a/vendor/plugins/nested_has_many_through/Rakefile b/vendor/plugins/nested_has_many_through/Rakefile new file mode 100644 index 0000000..ecc8b5f --- /dev/null +++ b/vendor/plugins/nested_has_many_through/Rakefile @@ -0,0 +1,77 @@ +# use pluginized rpsec if it exists +rspec_base = File.expand_path(File.dirname(__FILE__) + '/../rspec/lib') +$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) and !$LOAD_PATH.include?(rspec_base) + +require 'spec/rake/spectask' +require 'spec/rake/verify_rcov' +require 'rake/rdoctask' + +plugin_name = 'nested_has_many_through' + +task :default => :spec + +desc "Run the specs for #{plugin_name}" +Spec::Rake::SpecTask.new(:spec) do |t| + t.spec_files = FileList['spec/**/*_spec.rb'] + t.spec_opts = ["--colour"] +end + +namespace :spec do + desc "Generate RCov report for #{plugin_name}" + Spec::Rake::SpecTask.new(:rcov) do |t| + t.spec_files = FileList['spec/**/*_spec.rb'] + t.rcov = true + t.rcov_dir = 'doc/coverage' + t.rcov_opts = ['--text-report', '--exclude', "spec/,rcov.rb,#{File.expand_path(File.join(File.dirname(__FILE__),'../../..'))}"] + end + + namespace :rcov do + desc "Verify RCov threshold for #{plugin_name}" + RCov::VerifyTask.new(:verify => "spec:rcov") do |t| + t.threshold = 97.1 + t.index_html = File.join(File.dirname(__FILE__), 'doc/coverage/index.html') + end + end + + desc "Generate specdoc for #{plugin_name}" + Spec::Rake::SpecTask.new(:doc) do |t| + t.spec_files = FileList['spec/**/*_spec.rb'] + t.spec_opts = ["--format", "specdoc:SPECDOC"] + end + + namespace :doc do + desc "Generate html specdoc for #{plugin_name}" + Spec::Rake::SpecTask.new(:html => :rdoc) do |t| + t.spec_files = FileList['spec/**/*_spec.rb'] + t.spec_opts = ["--format", "html:doc/rspec_report.html", "--diff"] + end + end +end + +task :rdoc => :doc +task "SPECDOC" => "spec:doc" + +desc "Generate rdoc for #{plugin_name}" +Rake::RDocTask.new(:doc) do |t| + t.rdoc_dir = 'doc' + t.main = 'README.rdoc' + t.title = "#{plugin_name}" + t.template = ENV['RDOC_TEMPLATE'] + t.options = ['--line-numbers', '--inline-source'] + t.rdoc_files.include('README.rdoc', 'SPECDOC', 'MIT-LICENSE') + t.rdoc_files.include('lib/**/*.rb') +end + +namespace :doc do + desc "Generate all documentation (rdoc, specdoc, specdoc html and rcov) for #{plugin_name}" + task :all => ["spec:doc:html", "spec:doc", "spec:rcov", "doc"] +end + +task :cruise do + # run the garlic task, capture the output, if succesful make the docs and copy them to ardes + sh "garlic all" + `garlic run > .garlic/report.txt` + `scp -i ~/.ssh/ardes .garlic/report.txt ardes@ardes.com:~/subdomains/plugins/httpdocs/doc/#{plugin_name}_garlic_report.txt` + `cd .garlic/*/vendor/plugins/#{plugin_name}; rake doc:all; scp -i ~/.ssh/ardes -r doc ardes@ardes.com:~/subdomains/plugins/httpdocs/doc/#{plugin_name}` + puts "The build is GOOD" +end diff --git a/vendor/plugins/nested_has_many_through/SPECDOC b/vendor/plugins/nested_has_many_through/SPECDOC new file mode 100644 index 0000000..6ce019f --- /dev/null +++ b/vendor/plugins/nested_has_many_through/SPECDOC @@ -0,0 +1,49 @@ + +Author (newly created) +- #posts should == [] +- #categories should == [] +- #similar_posts should == [] +- #similar_authors should == [] +- #commenters should == [] + +Author (newly created) who creates post with category +- #posts should == [post] +- #categories should == [category] + +Author (newly created) who creates post with category and @other_author creates post2 in category +- #posts should == [post2] +- #categories should == [category] +- #similar_posts.should == [post, post2] +- #similar_authors.should == [@author, @other_author] + +Author (newly created) who creates post with category and @other_author creates post2 in category and creates @other_post in @other_category +- #similar_posts.should == [@post, @post2] +- #posts_by_similar_authors.should == [@post, @post2, @other_post] + +Commenter use case (a1: p1>c1, a2: p2>c1, p3>c2, a3: p4>c3) +- a1.posts should == [p1] +- a1.categories should == [c1] +- a2.posts should == [p2, p3] +- a2.categories should == [c1, c2] + +Commenter use case (a1: p1>c1, a2: p2>c1, p3>c2, a3: p4>c3) u1 comments on p2 +- u1.comments should == [comment] +- a1.commenters should be empty +- a2.commenters should == [u1] +- u1.commented_posts should == [p2] +- u1.commented_posts.find_inflamatory(:all) should be empty +- u1.commented_posts.inflamatory should be empty +- u1.commented_authors should == [a2] +- u1.posts_of_interest should == [p1, p2, p3] +- u1.categories_of_interest should == [c1, c2] + +Commenter use case (a1: p1>c1, a2: p2>c1, p3>c2, a3: p4>c3) u1 comments on p2 when p2 is inflamatory +- p2 should be inflamatory +- u1.commented_posts.find_inflamatory(:all) should == [p2] +- u1.posts_of_interest.find_inflamatory(:all) should == [p2] +- u1.commented_posts.inflamatory should == [p2] +- u1.posts_of_interest.inflamatory should == [p2] + +Finished in 0.538693 seconds + +31 examples, 0 failures diff --git a/vendor/plugins/nested_has_many_through/TODO b/vendor/plugins/nested_has_many_through/TODO new file mode 100644 index 0000000..76e4409 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/TODO @@ -0,0 +1,10 @@ +* get C2 up to 100% + - spec a polymorphic relationship + +* quote table names + +* make more use of rails in construct_has_many_or_belongs_to_attributes to reduce brittleness + +* Add more coverage + - scopes + - raise an error when nhmt is being used in a perverse way \ No newline at end of file diff --git a/vendor/plugins/nested_has_many_through/garlic.rb b/vendor/plugins/nested_has_many_through/garlic.rb new file mode 100644 index 0000000..57c0b85 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/garlic.rb @@ -0,0 +1,27 @@ +garlic do + repo 'nested_has_many_through', :path => '.' + + repo 'rails', :url => 'git://github.com/rails/rails' + repo 'rspec', :url => 'git://github.com/dchelimsky/rspec' + repo 'rspec-rails', :url => 'git://github.com/dchelimsky/rspec-rails' + + # target rails versions + ['origin/2-2-stable', 'origin/2-1-stable', 'origin/2-0-stable'].each do |rails| + # specify how to prepare app and run CI task + target "Rails: #{rails}", :tree_ish => rails do + prepare do + plugin 'rspec' + plugin 'rspec-rails' do + `script/generate rspec -f` + end + plugin 'nested_has_many_through', :clone => true + end + + run do + cd "vendor/plugins/nested_has_many_through" do + sh "rake spec:rcov:verify" + end + end + end + end +end diff --git a/vendor/plugins/nested_has_many_through/init.rb b/vendor/plugins/nested_has_many_through/init.rb new file mode 100644 index 0000000..ccd759b --- /dev/null +++ b/vendor/plugins/nested_has_many_through/init.rb @@ -0,0 +1,10 @@ +require 'nested_has_many_through' + +ActiveRecord::Associations::HasManyThroughAssociation.send :include, NestedHasManyThrough::Association + +# BC +if defined?(ActiveRecord::Reflection::ThroughReflection) + ActiveRecord::Reflection::ThroughReflection.send :include, NestedHasManyThrough::Reflection +else + ActiveRecord::Reflection::AssociationReflection.send :include, NestedHasManyThrough::Reflection +end \ No newline at end of file diff --git a/vendor/plugins/nested_has_many_through/lib/nested_has_many_through.rb b/vendor/plugins/nested_has_many_through/lib/nested_has_many_through.rb new file mode 100644 index 0000000..958efb7 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/lib/nested_has_many_through.rb @@ -0,0 +1,148 @@ +module NestedHasManyThrough + module Reflection # :nodoc: + def self.included(base) + base.send :alias_method_chain, :check_validity!, :nested_has_many_through + end + + def check_validity_with_nested_has_many_through! + check_validity_without_nested_has_many_through! + rescue ActiveRecord::HasManyThroughSourceAssociationMacroError => e + # now we permit has many through to a :though source + raise e unless source_reflection.options[:through] + end + end + + module Association + def self.included(base) + base.class_eval do + alias_method :original_construct_conditions, :construct_conditions + alias_method :original_construct_joins, :construct_joins + + def construct_conditions + if @reflection.macro == :has_one + original_construct_conditions + else + @nested_join_attributes ||= construct_nested_join_attributes + "#{@nested_join_attributes[:remote_key]} = #{@owner.quoted_id} #{@nested_join_attributes[:conditions]}" + end + end + + def construct_joins(custom_joins = nil) + if @reflection.macro == :has_one + original_construct_joins(custom_joins) + else + @nested_join_attributes ||= construct_nested_join_attributes + "#{@nested_join_attributes[:joins]} #{custom_joins}" + end + end + end + end + + protected + # Given any belongs_to or has_many (including has_many :through) association, + # return the essential components of a join corresponding to that association, namely: + # + # * :joins: any additional joins required to get from the association's table + # (reflection.table_name) to the table that's actually joining to the active record's table + # * :remote_key: the name of the key in the join table (qualified by table name) which will join + # to a field of the active record's table + # * :local_key: the name of the key in the local table (not qualified by table name) which will + # take part in the join + # * :conditions: any additional conditions (e.g. filtering by type for a polymorphic association, + # or a :conditions clause explicitly given in the association), including a leading AND + def construct_nested_join_attributes( reflection = @reflection, + association_class = reflection.klass, + table_ids = {association_class.table_name => 1}) + if reflection.macro == :has_many && reflection.through_reflection + construct_has_many_through_attributes(reflection, table_ids) + else + construct_has_many_or_belongs_to_attributes(reflection, association_class, table_ids) + end + end + + def construct_has_many_through_attributes(reflection, table_ids) + # Construct the join components of the source association, so that we have a path from + # the eventual target table of the association up to the table named in :through, and + # all tables involved are allocated table IDs. + source_attrs = construct_nested_join_attributes(reflection.source_reflection, reflection.klass, table_ids) + + # Determine the alias of the :through table; this will be the last table assigned + # when constructing the source join components above. + through_table_alias = through_table_name = reflection.through_reflection.table_name + through_table_alias += "_#{table_ids[through_table_name]}" unless table_ids[through_table_name] == 1 + + # Construct the join components of the through association, so that we have a path to + # the active record's table. + through_attrs = construct_nested_join_attributes(reflection.through_reflection, reflection.through_reflection.klass, table_ids) + + # Any subsequent joins / filters on owner attributes will act on the through association, + # so that's what we return for the conditions/keys of the overall association. + conditions = through_attrs[:conditions] + conditions += " AND #{interpolate_sql(reflection.klass.send(:sanitize_sql, reflection.options[:conditions]))}" if reflection.options[:conditions] + + { + :joins => "%s INNER JOIN %s ON ( %s = %s.%s %s) %s %s" % [ + source_attrs[:joins], + through_table_name == through_table_alias ? through_table_name : "#{through_table_name} #{through_table_alias}", + source_attrs[:remote_key], + through_table_alias, source_attrs[:local_key], + source_attrs[:conditions], + through_attrs[:joins], + reflection.options[:joins] + ], + :remote_key => through_attrs[:remote_key], + :local_key => through_attrs[:local_key], + :conditions => conditions + } + end + + + # reflection is not has_many :through; it's a standard has_many / belongs_to instead + # TODO: see if we can defer to rails code here a bit more + def construct_has_many_or_belongs_to_attributes(reflection, association_class, table_ids) + # Determine the alias used for remote_table_name, if any. In all cases this will already + # have been assigned an ID in table_ids (either through being involved in a previous join, + # or - if it's the first table in the query - as the default value of table_ids) + remote_table_alias = remote_table_name = association_class.table_name + remote_table_alias += "_#{table_ids[remote_table_name]}" unless table_ids[remote_table_name] == 1 + + # Assign a new alias for the local table. + local_table_alias = local_table_name = reflection.active_record.table_name + if table_ids[local_table_name] + table_id = table_ids[local_table_name] += 1 + local_table_alias += "_#{table_id}" + else + table_ids[local_table_name] = 1 + end + + conditions = '' + # Add filter for single-table inheritance, if applicable. + conditions += " AND #{remote_table_alias}.#{association_class.inheritance_column} = #{association_class.quote_value(association_class.name.demodulize)}" unless association_class.descends_from_active_record? + # Add custom conditions + conditions += " AND (#{interpolate_sql(association_class.send(:sanitize_sql, reflection.options[:conditions]))})" if reflection.options[:conditions] + + if reflection.macro == :belongs_to + if reflection.options[:polymorphic] + conditions += " AND #{local_table_alias}.#{reflection.options[:foreign_type]} = #{reflection.active_record.quote_value(association_class.base_class.name.to_s)}" + end + { + :joins => reflection.options[:joins], + :remote_key => "#{remote_table_alias}.#{association_class.primary_key}", + :local_key => reflection.primary_key_name, + :conditions => conditions + } + else + # Association is has_many (without :through) + if reflection.options[:as] + conditions += " AND #{remote_table_alias}.#{reflection.options[:as]}_type = #{reflection.active_record.quote_value(reflection.active_record.base_class.name.to_s)}" + end + { + :joins => "#{reflection.options[:joins]}", + :remote_key => "#{remote_table_alias}.#{reflection.primary_key_name}", + :local_key => reflection.klass.primary_key, + :conditions => conditions + } + end + end + end +end diff --git a/vendor/plugins/nested_has_many_through/spec/app.rb b/vendor/plugins/nested_has_many_through/spec/app.rb new file mode 100644 index 0000000..71c7c4e --- /dev/null +++ b/vendor/plugins/nested_has_many_through/spec/app.rb @@ -0,0 +1,84 @@ +# Testing app setup + +################## +# Database schema +################## + +ActiveRecord::Migration.suppress_messages do + ActiveRecord::Schema.define(:version => 0) do + create_table :users, :force => true do |t| + t.column "type", :string + end + + create_table :posts, :force => true do |t| + t.column "author_id", :integer + t.column "category_id", :integer + t.column "inflamatory", :boolean + end + + create_table :categories, :force => true do |t| + end + + create_table :comments, :force => true do |t| + t.column "user_id", :integer + t.column "post_id", :integer + end + end +end + +######### +# Models +# +# Domain model is this: +# +# - authors (type of user) can create posts in categories +# - users can comment on posts +# - authors have similar_posts: posts in the same categories as ther posts +# - authors have similar_authors: authors of the recommended_posts +# - authors have posts_of_similar_authors: all posts by similar authors (not just the similar posts, +# similar_posts is be a subset of this collection) +# - authors have commenters: users who have commented on their posts +# +class User < ActiveRecord::Base + has_many :comments + has_many :commented_posts, :through => :comments, :source => :post, :uniq => true + has_many :commented_authors, :through => :commented_posts, :source => :author, :uniq => true + has_many :posts_of_interest, :through => :commented_authors, :source => :posts_of_similar_authors, :uniq => true + has_many :categories_of_interest, :through => :posts_of_interest, :source => :category, :uniq => true +end + +class Author < User + has_many :posts + has_many :categories, :through => :posts + has_many :similar_posts, :through => :categories, :source => :posts + has_many :similar_authors, :through => :similar_posts, :source => :author, :uniq => true + has_many :posts_of_similar_authors, :through => :similar_authors, :source => :posts, :uniq => true + has_many :commenters, :through => :posts, :uniq => true +end + +class Post < ActiveRecord::Base + + # testing with_scope + def self.find_inflamatory(*args) + with_scope :find => {:conditions => {:inflamatory => true}} do + find(*args) + end + end + + # only test named_scope in edge + named_scope(:inflamatory, :conditions => {:inflamatory => true}) if respond_to?(:named_scope) + + belongs_to :author + belongs_to :category + has_many :comments + has_many :commenters, :through => :comments, :source => :user, :uniq => true +end + +class Category < ActiveRecord::Base + has_many :posts +end + +class Comment < ActiveRecord::Base + belongs_to :user + belongs_to :post +end \ No newline at end of file diff --git a/vendor/plugins/nested_has_many_through/spec/models/author_spec.rb b/vendor/plugins/nested_has_many_through/spec/models/author_spec.rb new file mode 100644 index 0000000..36ccf18 --- /dev/null +++ b/vendor/plugins/nested_has_many_through/spec/models/author_spec.rb @@ -0,0 +1,85 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper')) +require File.expand_path(File.join(File.dirname(__FILE__), '../app')) + +describe Author do + describe "(newly created)" do + before do + @category = Category.create! + @other_category = Category.create! + @author = Author.create! + end + + it "#posts should == []" do + @author.posts.should == [] + end + + it "#categories should == []" do + @author.categories.should == [] + end + + it "#similar_posts should == []" do + @author.similar_posts.should == [] + end + + it "#similar_authors should == []" do + @author.similar_authors.should == [] + end + + it "#commenters should == []" do + @author.commenters.should == [] + end + + describe "who creates post with category" do + before do + @post = Post.create! :author => @author, :category => @category + end + + it "#posts should == [post]" do + @author.posts.should == [@post] + end + + it "#categories should == [category]" do + @author.categories.should == [@category] + end + + describe "and @other_author creates post2 in category" do + + before do + @other_author = Author.create! + @post2 = Post.create! :author => @other_author, :category => @category + end + + it "#posts should == [post2]" do + @author.posts.should == [@post] + end + + it "#categories should == [category]" do + @author.categories.should == [@category] + end + + it "#similar_posts.should == [post, post2]" do + @author.similar_posts.should == [@post, @post2] + end + + it "#similar_authors.should == [@author, @other_author]" do + @author.similar_authors.should == [@author, @other_author] + end + + describe "and creates @other_post in @other_category" do + before do + @other_category = Category.create! + @other_post = Post.create! :author => @other_author, :category => @other_category + end + + it "#similar_posts.should == [@post, @post2]" do + @author.similar_posts.should == [@post, @post2] + end + + it "#posts_by_similar_authors.should == [@post, @post2, @other_post]" do + @author.posts_of_similar_authors.should == [@post, @post2, @other_post] + end + end + end + end + end +end \ No newline at end of file diff --git a/vendor/plugins/nested_has_many_through/spec/models/commenter_spec.rb b/vendor/plugins/nested_has_many_through/spec/models/commenter_spec.rb new file mode 100644 index 0000000..b57b3ce --- /dev/null +++ b/vendor/plugins/nested_has_many_through/spec/models/commenter_spec.rb @@ -0,0 +1,109 @@ +require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper')) +require File.expand_path(File.join(File.dirname(__FILE__), '../app')) + +describe 'Commenter use case (a1: p1>c1, a2: p2>c1, p3>c2, a3: p4>c3)' do + before do + @c1 = Category.create! + @c2 = Category.create! + @c3 = Category.create! + @a1 = Author.create! + @a2 = Author.create! + @a3 = Author.create! + @p1 = @a1.posts.create! :category => @c1 + @p2 = @a2.posts.create! :category => @c1 + @p3 = @a2.posts.create! :category => @c2 + @p4 = @a3.posts.create! :category => @c3 + @a1.reload + @a2.reload + end + + it "a1.posts should == [p1]" do + @a1.posts.should == [@p1] + end + + it "a1.categories should == [c1]" do + @a1.categories.should == [@c1] + end + + it "a2.posts should == [p2, p3]" do + @a2.posts.should == [@p2, @p3] + end + + it "a2.categories should == [c1, c2]" do + @a2.categories.should == [@c1, @c2] + end + + describe "u1 comments on p2" do + before do + @u1 = User.create! + @comment = @p2.comments.create! :user => @u1 + end + + it "u1.comments should == [comment]" do + @u1.comments.should == [@comment] + end + + it "a1.commenters should be empty" do + @a1.commenters.should be_empty + end + + it "a2.commenters should == [u1]" do + @a2.commenters.should == [@u1] + end + + it "u1.commented_posts should == [p2]" do + @u1.commented_posts.should == [@p2] + end + + it "u1.commented_posts.find_inflamatory(:all) should be empty" do + @u1.commented_posts.find_inflamatory(:all).should be_empty + end + + if ActiveRecord::Base.respond_to?(:named_scope) + it "u1.commented_posts.inflamatory should be empty" do + @u1.commented_posts.inflamatory.should be_empty + end + end + + it "u1.commented_authors should == [a2]" do + @u1.commented_authors.should == [@a2] + end + + it "u1.posts_of_interest should == [p1, p2, p3]" do + @u1.posts_of_interest.should == [@p1, @p2, @p3] + end + + it "u1.categories_of_interest should == [c1, c2]" do + @u1.categories_of_interest.should == [@c1, @c2] + end + + describe "when p2 is inflamatory" do + before do + @p2.toggle!(:inflamatory) + end + + it "p2 should be inflamatory" do + @p2.should be_inflamatory + end + + it "u1.commented_posts.find_inflamatory(:all) should == [p2]" do + # uniq ids is here (and next spec) because eager loading changed behaviour 2.0.2 => edge + @u1.commented_posts.find_inflamatory(:all).collect(&:id).uniq.should == [@p2.id] + end + + it "u1.posts_of_interest.find_inflamatory(:all).uniq should == [p2]" do + @u1.posts_of_interest.find_inflamatory(:all).collect(&:id).uniq.should == [@p2.id] + end + + if ActiveRecord::Base.respond_to?(:named_scope) + it "u1.commented_posts.inflamatory should == [p2]" do + @u1.commented_posts.inflamatory.should == [@p2] + end + + it "u1.posts_of_interest.inflamatory should == [p2]" do + @u1.posts_of_interest.inflamatory.should == [@p2] + end + end + end + end +end diff --git a/vendor/plugins/nested_has_many_through/spec/spec_helper.rb b/vendor/plugins/nested_has_many_through/spec/spec_helper.rb new file mode 100644 index 0000000..8e21f5b --- /dev/null +++ b/vendor/plugins/nested_has_many_through/spec/spec_helper.rb @@ -0,0 +1,23 @@ +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] ||= "test" +require File.expand_path(File.join(File.dirname(__FILE__), "../../../../config/environment")) +require 'spec/rails' + +Spec::Runner.configure do |config| + config.use_transactional_fixtures = true + config.use_instantiated_fixtures = false + config.fixture_path = RAILS_ROOT + '/spec/fixtures' + + # You can declare fixtures for each behaviour like this: + # describe "...." do + # fixtures :table_a, :table_b + # + # Alternatively, if you prefer to declare them only once, you can + # do so here, like so ... + # + # config.global_fixtures = :table_a, :table_b + # + # If you declare global fixtures, be aware that they will be declared + # for all of your examples, even those that don't use them. +end \ No newline at end of file -- libgit2 0.21.2