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