Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add specs

It's certainly not a best practice to wait 3 years before adding
specs for a library you are using in production, but better late
than never.

This adds specs for both ActiveRecord and Sequel, which should
have close to 100% line coverage.
  • Loading branch information...
commit 7ade3a7dca446bfcfe41ed57376f016c45e04b9c 1 parent a22a22a
@jeremyevans authored
View
6 .gitignore
@@ -1,2 +1,4 @@
-rdoc/
-*.gem
+/rdoc/
+/*.gem
+/spec/db
+/coverage
View
15 README
@@ -7,7 +7,7 @@ the following features:
- Fixtures specify association names instead of foreign keys
- Support both Sequel and ActiveRecord
- Supports many_to_one/belongs_to, one_to_many/has_many,
- many_to_many/has_and_belongs_to_many, and has_one associations
+ many_to_many/has_and_belongs_to_many, and has_one/one_to_one associations
- Loads a fixture's dependency graph in such a manner that foreign key
constraints aren't violated
- Has a very simple API (FixtureDependencies.load(:model__fixture))
@@ -128,7 +128,7 @@ using the following syntax:
This would load just the jeremy fixture and its dependencies. I find this is
much better than loading all fixtures in most of my test suites. Even better
-is loading just the fixtures you want instead every test method (see below).
+is loading just the fixtures you want inside every test method (see below).
This leads to the most robust testing.
== Loading fixtures inside test methods
@@ -244,6 +244,13 @@ test/test_helper.rb:
This will give a verbose description of the loading and saving of fixtures for
every test, including the recursive loading of the dependency graph.
+== Specs
+
+The specs for fixture dependencies and be run with Rake. They require
+the sequel, activerecord, and sqlite3 gems installed. The default rake task
+runs the specs. You should run the spec_migrate task first to create the
+spec database.
+
== Similar Ideas
Rails now supports something similar by default. Honestly, I'm not sure what
@@ -255,8 +262,8 @@ it doesn't support has_* associations.
== License
-fixture_dependencies is released under the MIT License. See the LICENSE file
-for details.
+fixture_dependencies is released under the MIT License. See the MIT-LICENSE
+file for details.
== Author
View
27 Rakefile
@@ -20,3 +20,30 @@ desc "Package fixture_dependencies"
task :package do
sh %{gem build fixture_dependencies.gemspec}
end
+
+begin
+ require 'spec/rake/spectask'
+
+ desc "Run Sequel specs"
+ Spec::Rake::SpecTask.new(:spec_sequel) do |t|
+ t.spec_files = Dir['spec/*_spec.rb']
+ #t.rcov = true
+ end
+
+ desc "Run ActiveRecord specs"
+ Spec::Rake::SpecTask.new(:spec_ar) do |t|
+ ENV['FD_AR'] = '1'
+ t.spec_files = Dir['spec/*_spec.rb']
+ #t.rcov = true
+ end
+
+ desc "Run Sequel and ActiveRecord specs"
+ task :default=>[:spec_sequel, :spec_ar]
+rescue LoadError
+end
+
+desc "Create spec database"
+task :spec_migrate do
+ sh %{mkdir -p spec/db}
+ sh %{sequel -m spec/migrate -E sqlite://spec/db/fd_spec.sqlite3}
+end
View
21 spec/ar_spec_helper.rb
@@ -0,0 +1,21 @@
+require 'active_record'
+
+ActiveRecord::Base.establish_connection(:adapter=>'sqlite3', :database=>File.join(File.dirname(File.expand_path(__FILE__)), 'db', 'fd_spec.sqlite3'))
+
+class Artist < ActiveRecord::Base
+ has_many :albums
+end
+
+class Album < ActiveRecord::Base
+ belongs_to :artist
+ has_and_belongs_to_many :tags
+end
+
+class Tag < ActiveRecord::Base
+ has_and_belongs_to_many :albums
+end
+
+class SelfRef < ActiveRecord::Base
+ belongs_to :self_ref
+ has_many :self_refs
+end
View
124 spec/fd_spec.rb
@@ -0,0 +1,124 @@
+require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper')
+
+describe FixtureDependencies do
+ def load(*a) FixtureDependencies.load(*a) end
+ def verbose(i=3)
+ v = FixtureDependencies.verbose
+ FixtureDependencies.verbose = i
+ yield
+ ensure
+ FixtureDependencies.verbose = v
+ end
+
+ after do
+ # Clear tables and fixture_dependencies caches
+ [:self_refs, :albums_tags, :tags, :albums, :artists].each{|x| DB[x].delete}
+ FixtureDependencies.loaded.clear
+ FixtureDependencies.fixtures.clear
+ end
+
+ it "should load single records with underscore syntax" do
+ ym = load(:artist__ym)
+ ym.id.should == 1
+ ym.name.should == 'YM'
+ end
+
+ it "should load multiple records with underscore syntax and multiple arguments" do
+ rf, mo = load(:album__rf, :album__mo)
+ rf.id.should == 1
+ rf.name.should == 'RF'
+ mo.id.should == 2
+ mo.name.should == 'MO'
+ end
+
+ it "should load multiple records with hash syntax" do
+ rf, mo = load(:albums=>[:rf, :mo])
+ rf.id.should == 1
+ rf.name.should == 'RF'
+ mo.id.should == 2
+ mo.name.should == 'MO'
+ end
+
+ it "should load multiple records with a mix a hashes and symbols" do
+ rf, mo = load(:album__rf, :albums=>[:mo])
+ rf.id.should == 1
+ rf.name.should == 'RF'
+ mo.id.should == 2
+ mo.name.should == 'MO'
+ end
+
+ it "should load whole tables at once with single symbol" do
+ Artist.count.should == 0
+ load(:artists)
+ Artist.count.should == 2
+ end
+
+ it "should load whole tables at once with single symbol" do
+ Artist.count.should == 0
+ Album.count.should == 0
+ load(:artists, :albums)
+ Artist.count.should == 2
+ Album.count.should == 3
+ end
+
+ it "should load associated many_to_one records" do
+ rf = load(:album__rf)
+ rf.artist.id.should == 1
+ end
+
+ it "should load associated one_to_many records" do
+ nu = load(:artist__nu)
+ nu.albums.length.should == 1
+ nu.albums.first.id.should == 3
+ nu.albums.first.name.should == 'P'
+ end
+
+ it "should load associated many_to_many records and handle cycles (I->P->NU->P)" do
+ i = load(:tag__i)
+ i.albums.length.should == 1
+ p = i.albums.first
+ p.id.should == 3
+ p.name.should == 'P'
+ nu = p.artist
+ nu.id.should == 2
+ nu.name.should == 'NU'
+ nu.albums.length.should == 1
+ nu.albums.first.should == p
+ end
+
+ it "should not load records that were not asked for" do
+ ym = load(:artist__ym)
+ Artist.count.should == 1
+ Artist.first.should == ym
+ load(:artist__nu)
+ Artist.count.should == 2
+ end
+
+ it "should handle self referential records" do
+ i = load(:self_ref__i)
+ i.id.should == 1
+ i.self_ref.id.should == 1
+ i.self_refs.length.should == 1
+ i.self_refs.first.id.should == 1
+ end
+
+ it "should handle association cycles" do
+ a = load(:self_ref__a)
+ a.id.should == 2
+ b = a.self_ref
+ b.id.should == 3
+ c = b.self_ref
+ c.id.should == 4
+ c.self_ref.should == a
+ end
+
+ it "should raise error nonexistent fixture files" do
+ class Foo < Sequel::Model; end
+ proc{load(:foos)}.should raise_error(ArgumentError)
+ end
+
+ it "should raise error for unsupported model classes" do
+ class Bar; def self.table_name() :bars end end
+ proc{load(:bars)}.should raise_error(TypeError)
+ end
+end
View
12 spec/fixtures/albums.yml
@@ -0,0 +1,12 @@
+rf:
+ id: 1
+ name: RF
+ artist: ym
+mo:
+ id: 2
+ name: MO
+ artist: ym
+p:
+ id: 3
+ name: P
+ artist: nu
View
7 spec/fixtures/artists.yml
@@ -0,0 +1,7 @@
+ym:
+ id: 1
+ name: YM
+nu:
+ id: 2
+ name: NU
+ albums: p
View
2  spec/fixtures/bars.yml
@@ -0,0 +1,2 @@
+i:
+ id: 1
View
14 spec/fixtures/self_refs.yml.erb
@@ -0,0 +1,14 @@
+i:
+ id: 1
+ self_ref: i
+ self_refs: [i]
+a:
+ id: 2
+ self_ref: b
+b:
+ id: 3
+ self_ref: c
+c:
+ id: 4
+ self_ref: a
+
View
7 spec/fixtures/tags.yml
@@ -0,0 +1,7 @@
+m:
+ id: 1
+ name: M
+i:
+ id: 2
+ name: I
+ albums: p
View
10 spec/migrate/001_tables.rb
@@ -0,0 +1,10 @@
+Sequel.migration do
+ change do
+ create_table(:artists){primary_key :id; String :name}
+ create_table(:albums){primary_key :id; String :name; foreign_key :artist_id, :artists}
+ create_table(:tags){primary_key :id; String :name}
+ create_table(:albums_tags){foreign_key :album_id, :albums; foreign_key :tag_id, :tags; primary_key [:album_id, :tag_id]}
+
+ create_table(:self_refs){primary_key :id; foreign_key :self_ref_id, :self_refs}
+ end
+end
View
31 spec/sequel_spec_helper.rb
@@ -0,0 +1,31 @@
+class Artist < Sequel::Model
+ one_to_many :albums
+end
+
+class Album < Sequel::Model
+ many_to_one :artist
+ many_to_many :tags
+end
+
+class Tag < Sequel::Model
+ many_to_many :albums
+end
+
+class SelfRef < Sequel::Model
+ many_to_one :self_ref
+ one_to_many :self_refs
+end
+
+class ComArtist < Sequel::Model
+ one_to_many :com_albums, :key=>[:artist_id1, :artist_id2]
+end
+
+class ComAlbum < Sequel::Model
+ many_to_one :com_artist, :key=>[:artist_id1, :artist_id2]
+ many_to_many :com_tags, :left_key=>[:album_id1, :album_id2], :right_key=>[:tag_id1, :tag_id2]
+end
+
+class ComTag < Sequel::Model
+ many_to_many :com_albums, :right_key=>[:album_id1, :album_id2], :left_key=>[:tag_id1, :tag_id2]
+end
+
View
13 spec/spec_helper.rb
@@ -0,0 +1,13 @@
+require 'rubygems'
+require 'sequel'
+
+DB = Sequel.sqlite(File.join(File.dirname(File.expand_path(__FILE__)), 'db', 'fd_spec.sqlite3'))
+
+require File.join(File.dirname(File.expand_path(__FILE__)),"#{ENV['FD_AR'] ? 'ar' : 'sequel'}_spec_helper")
+
+$:.unshift(File.join(File.dirname(File.dirname(File.expand_path(__FILE__))), 'lib'))
+require 'fixture_dependencies'
+FixtureDependencies.fixture_path = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures')
+#FixtureDependencies.verbose = 3
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.