lib/joinfix/fixtures_class.rb in joinfix-0.1.0 vs lib/joinfix/fixtures_class.rb in joinfix-0.1.1
- old
+ new
@@ -21,82 +21,147 @@
# Retreives the fixture by the given table name. Raises an error if the fixture has
# not yet been loaded.
def fixture(table_name)
fixture = all_loaded_fixtures[table_name.to_s]
- raise ArgumentError, "No fixture loaded for: #{table_name}" unless fixture
+ raise MissingFixtureError.new(table_name) unless fixture
fixture
end
protected
+ # Sets the primary key in each of the input fixtures, beginning one-past fixtures.offset
+ # (generally this is 1). If a fixture already has an id assigned, it will be skipped.
def index_fixtures(fixtures)
+ id = fixtures.klass.primary_key
+
# first find entries with an id and record the ids so that they will be skipped
skip_indicies = []
fixtures.each_pair do |name, fixture|
- skip_indicies << fixture["id"].to_i if fixture.has_key?("id")
+ skip_indicies << fixture[id].to_i if fixture.has_key?(id)
end
# next find and index entries that do not have an id defined
index = fixtures.offset
fixtures.each_pair do |name, fixture|
# skip entries that already have an id defined
- next if fixture.has_key?("id")
-
+ next if fixture.has_key?(id)
+
# find the next available index
# note this must happen before the id assignment,
# in case index 1 is marked for skipping
while true
index += 1
break unless skip_indicies.include?(index)
end
- fixture["id"] = index
+ fixture[id] = index
end
end
+ # Resolves each join reference in the input fixtures
def resolve_references(fixtures)
- fixtures.each_pair do |name, fixture|
+ fixtures.each_pair do |entry_name, fixture|
# search the fixture for join references
fixture.each_pair do |join_ref, join_name|
# next if the key isn't a join reference
next unless join_ref.kind_of?(Array)
foreign_key = join_ref.first
join_table_name = join_ref.last
-
- # next if the foreign key is already defined
- next if fixture.has_key?(foreign_key)
-
- begin
- # raise an error if the join table isn't loaded; the reference cannot be resolved
- unless Fixtures.all_loaded_fixtures.has_key?(join_table_name)
- raise ArgumentError, "The join table '#{join_table_name}' has not been loaded."
- end
+
+ # raise an error if the join table isn't loaded; the reference cannot be resolved
+ unless Fixtures.all_loaded_fixtures.has_key?(join_table_name)
+ raise ResolveJoinReferenceError.new(fixtures, entry_name, join_table_name, join_name,
+ "The join table '#{join_table_name}' has not been loaded.")
+ end
- join_fixtures = Fixtures.all_loaded_fixtures[join_table_name]
-
- # raise an error if the join entry isn't in the join table; the reference cannot be resolved
- unless join_fixtures.has_key?(join_name)
- raise ArgumentError, "The join entry '#{join_name}' doesn't exist in '#{join_table_name}'."
- end
+ join_fixtures = Fixtures.all_loaded_fixtures[join_table_name]
+ id = join_fixtures.klass.primary_key
+
+ # raise an error if the join entry isn't in the join table; the reference cannot be resolved
+ unless join_fixtures.has_key?(join_name)
+ raise ResolveJoinReferenceError.new(fixtures, entry_name, join_table_name, join_name,
+ "The join entry '#{join_name}' doesn't exist in '#{join_table_name}'.")
+ end
- join_entry = join_fixtures[join_name]
+ join_entry = join_fixtures[join_name]
- # raise an exception if a join_id was not found
- unless join_entry.has_key?("id")
- raise ArgumentError, "No id present in join entry '#{join_name}'."
- end
- rescue
- raise ArgumentError, "Cannot resolve reference '#{join_reference} => #{join_name}' in '#{@table_name}.#{name}'. #{$!}"
+ # raise an exception if a join_id was not found
+ unless join_entry.has_key?(id)
+ raise ResolveJoinReferenceError.new(fixtures, entry_name, join_table_name, join_name,
+ "No #{id} present in join entry '#{join_name}'.")
end
-
+
+ # raise an exception if the foreign key is already set
+ unless fixture[foreign_key].nil?
+ raise ForeignKeySetError.new(fixtures, entry_name, join_table_name, join_name,
+ "Foreign key <#{foreign_key}> is already set!")
+ end
+
# set the join id
- fixture[foreign_key] = join_entry["id"]
+ fixture[foreign_key] = join_entry[id]
end
# delete the join references
fixture.delete_if {|key,value| key.kind_of?(Array) }
end
end
+ end
+end
+
+class MissingFixtureError < RuntimeError # :nodoc:
+ attr_reader :table_name
+ def initialize(table_name)
+ @table_name = table_name
+ end
+
+ def message
+ "No fixture loaded for <#{table_name}>\n" +
+ (advice.nil? ? '' : "#{advice}\n")
+ end
+
+ def advice
+ %Q{}
+ end
+end
+
+class ResolveJoinReferenceError < RuntimeError # :nodoc:
+ attr_reader :fixtures, :entry_name, :join_table_name, :join_name, :msg
+ attr_accessor :advice
+
+ def initialize(fixtures, entry_name, join_table_name, join_name, msg=nil)
+ @fixtures = fixtures
+ @entry_name = entry_name
+ @join_table_name = join_table_name
+ @join_name = join_name
+ @msg =msg
+ end
+
+ def message
+ "Cannot resolve reference to <#{join_table_name}(:#{join_name})> " +
+ "for <#{fixtures.klass.table_name}(:#{entry_name})> " +
+ "in <#{fixtures.fixture_path}>.\n" +
+ (msg.nil? ? '' : "\n#{msg}\n") +
+ (advice.nil? ? '' : "#{advice}\n")
+ end
+end
+
+class ForeignKeySetError < ResolveJoinReferenceError # :nodoc:
+ def advice
+ %Q{
+This error occurs when you specifiy the foreign key, as well as a join entry.
+---
+poem:
+ title: Poetry of Departures
+ author_id: 8
+ author: larkin
+
+If you need to specify the foreign key, do so within the entry.
+---
+poem:
+ title: Poetry of Departures
+ author:
+ larkin:
+ id: 8}
end
end