Finished porting over MySQL import functionality.
* removed assertions on #num_inserts, that is db-specific and is handled in details by abstract_adapter_test.
This commit is contained in:
parent
e8271778b7
commit
075104a944
|
@ -289,7 +289,6 @@ class ActiveRecord::Base
|
|||
values_sql,
|
||||
"#{self.class.name} Create Many Without Validations Or Callbacks" )
|
||||
end
|
||||
|
||||
number_inserted
|
||||
end
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
|
||||
|
||||
describe "#import" do
|
||||
|
||||
it "should return the number of inserts performed" do
|
||||
# see ActiveRecord::ConnectionAdapters::AbstractAdapter test for more specifics
|
||||
assert_difference "Topic.count", +10 do
|
||||
result = Topic.import Build(3, :topics)
|
||||
assert_equal 3, result.num_inserts
|
||||
assert result.num_inserts > 0
|
||||
|
||||
result = Topic.import Build(7, :topics)
|
||||
assert_equal 7, result.num_inserts
|
||||
assert result.num_inserts > 0
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -21,14 +21,12 @@ describe "#import" do
|
|||
it "should import valid data" do
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import columns, valid_values, :validate => false
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
end
|
||||
|
||||
it "should import invalid data" do
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import columns, invalid_values, :validate => false
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -37,14 +35,12 @@ describe "#import" do
|
|||
it "should import valid data" do
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import columns, valid_values, :validate => true
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
end
|
||||
|
||||
it "should not import invalid data" do
|
||||
assert_no_difference "Topic.count" do
|
||||
result = Topic.import columns, invalid_values, :validate => true
|
||||
assert_equal 0, result.num_inserts
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -57,7 +53,6 @@ describe "#import" do
|
|||
it "should import valid data when mixed with invalid data" do
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import columns, valid_values + invalid_values, :validate => true
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
assert_equal 0, Topic.find_all_by_title(invalid_values.map(&:first)).count
|
||||
end
|
||||
|
@ -72,7 +67,6 @@ describe "#import" do
|
|||
it "should import records based on those model's attributes" do
|
||||
assert_difference "Topic.count", +9 do
|
||||
result = Topic.import topics
|
||||
assert_equal 9, result.num_inserts
|
||||
end
|
||||
|
||||
Topic.import [topic]
|
||||
|
@ -96,14 +90,12 @@ describe "#import" do
|
|||
it "should import valid models" do
|
||||
assert_difference "Topic.count", +9 do
|
||||
result = Topic.import topics, :validate => true
|
||||
assert_equal 9, result.num_inserts
|
||||
end
|
||||
end
|
||||
|
||||
it "should not import invalid models" do
|
||||
assert_no_difference "Topic.count" do
|
||||
result = Topic.import invalid_topics, :validate => true
|
||||
assert_equal 0, result.num_inserts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -112,7 +104,6 @@ describe "#import" do
|
|||
it "should import invalid models" do
|
||||
assert_difference "Topic.count", +7 do
|
||||
result = Topic.import invalid_topics, :validate => false
|
||||
assert_equal 7, result.num_inserts
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -124,7 +115,6 @@ describe "#import" do
|
|||
it "should import records populating the supplied columns with the corresponding model instance attributes" do
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import [:author_name, :title], topics
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
|
||||
# imported topics should be findable by their imported attributes
|
||||
|
@ -136,7 +126,6 @@ describe "#import" do
|
|||
topics.first.author_email_address = "zach.dennis@gmail.com"
|
||||
assert_difference "Topic.count", +2 do
|
||||
result = Topic.import [:author_name, :title], topics
|
||||
assert_equal 2, result.num_inserts
|
||||
end
|
||||
|
||||
assert !Topic.find_by_author_email_address("zach.dennis@gmail.com")
|
||||
|
@ -149,7 +138,6 @@ describe "#import" do
|
|||
Delorean.time_travel_to("5 minutes ago") do
|
||||
assert_difference "Book.count", +1 do
|
||||
result = Book.import [:title, :author_name, :publisher], [["LDAP", "Big Bird", "Del Rey"]]
|
||||
assert_equal 1, result.num_inserts
|
||||
end
|
||||
end
|
||||
@book = Book.last
|
||||
|
@ -179,27 +167,19 @@ describe "#import" do
|
|||
Delorean.time_travel_to("5 minutes ago") do
|
||||
assert_difference "Book.count", +1 do
|
||||
result = Book.import [:title, :author_name, :publisher], [["LDAP", "Big Bird", "Del Rey"]]
|
||||
assert_equal 1, result.num_inserts
|
||||
end
|
||||
end
|
||||
ActiveRecord::Base.default_timezone = original_timezone
|
||||
@book = Book.last
|
||||
end
|
||||
|
||||
it "should set the created_at column for new records respecting the time zone" do
|
||||
ActiveRecord::Base.default_timezone
|
||||
it "should set the created_at and created_on timestamps for new records" do
|
||||
assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.created_at.strftime("%H:%M")
|
||||
end
|
||||
|
||||
it "should set the created_on column for new records respecting the time zone" do
|
||||
assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.created_on.strftime("%H:%M")
|
||||
end
|
||||
|
||||
it "should set the updated_at column for new records respecting the time zone" do
|
||||
it "should set the updated_at and updated_on timestamps for new records" do
|
||||
assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.updated_at.strftime("%H:%M")
|
||||
end
|
||||
|
||||
it "should set the updated_on column for new records respecting the time zone" do
|
||||
assert_equal 5.minutes.ago.utc.strftime("%H:%M"), @book.updated_on.strftime("%H:%M")
|
||||
end
|
||||
end
|
||||
|
@ -211,7 +191,6 @@ describe "#import" do
|
|||
it "should import just fine" do
|
||||
assert_difference "Group.count", +1 do
|
||||
result = Group.import [group]
|
||||
assert_equal 1, result.num_inserts
|
||||
end
|
||||
assert_equal "superx", Group.first.order
|
||||
end
|
||||
|
|
|
@ -2,36 +2,25 @@ require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
|||
require "ar-extensions/import/mysql"
|
||||
|
||||
describe "#import with :on_duplicate_key_update option (mysql specific functionality)" do
|
||||
extend ActiveSupport::TestCase::MySQLAssertions
|
||||
|
||||
asssertion_group(:should_support_on_duplicate_key_update) do
|
||||
should_not_update_fields_not_mentioned
|
||||
should_update_foreign_keys
|
||||
should_not_update_created_at_on_timestamp_columns
|
||||
should_update_updated_at_on_timestamp_columns
|
||||
end
|
||||
|
||||
macro(:perform_import){ raise "supply your own #perform_import in a context below" }
|
||||
|
||||
assertion(:should_not_update_fields_not_mentioned) do
|
||||
assert_equal "John Doe", @topic.reload.author_name
|
||||
end
|
||||
|
||||
assertion(:should_update_fields_mentioned) do
|
||||
perform_import
|
||||
assert_equal "Book - 2nd Edition", @topic.reload.title
|
||||
assert_equal "johndoe@example.com", @topic.reload.author_email_address
|
||||
end
|
||||
|
||||
assertion(:should_update_fields_mentioned_with_hash_mappings) do
|
||||
perform_import
|
||||
assert_equal "johndoe@example.com", @topic.reload.title
|
||||
assert_equal "Book - 2nd Edition", @topic.reload.author_email_address
|
||||
end
|
||||
|
||||
assertion(:should_update_foreign_keys) do
|
||||
perform_import
|
||||
assert_equal 57, @topic.reload.parent_id
|
||||
end
|
||||
macro(:updated_topic){ Topic.find(@topic) }
|
||||
|
||||
context "given columns and values with :validation checks turned off" do
|
||||
let(:columns){ %w( id title author_name author_email_address parent_id ) }
|
||||
let(:values){ [ [ 99, "Book", "John Doe", "john@doe.com", 17 ] ] }
|
||||
let(:updated_values){ [ [ 99, "Book - 2nd Edition", "Author Should Not Change", "johndoe@example.com", 57 ] ] }
|
||||
|
||||
macro(:perform_import) do
|
||||
Topic.import columns, updated_values, :on_duplicate_key_update => update_columns, :validate => false
|
||||
macro(:perform_import) do |*opts|
|
||||
Topic.import columns, updated_values, opts.extract_options!.merge(:on_duplicate_key_update => update_columns, :validate => false)
|
||||
end
|
||||
|
||||
setup do
|
||||
|
@ -41,54 +30,48 @@ describe "#import with :on_duplicate_key_update option (mysql specific functiona
|
|||
|
||||
context "using string column names" do
|
||||
let(:update_columns){ [ "title", "author_email_address", "parent_id" ] }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol column names" do
|
||||
let(:update_columns){ [ :title, :author_email_address, :parent_id ] }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using string hash map" do
|
||||
let(:update_columns){ { "title" => "title", "author_email_address" => "author_email_address", "parent_id" => "parent_id" } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using string hash map, but specifying column mismatches" do
|
||||
let(:update_columns){ { "title" => "author_email_address", "author_email_address" => "title", "parent_id" => "parent_id" } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned_with_hash_mappings
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol hash map" do
|
||||
let(:update_columns){ { :title => :title, :author_email_address => :author_email_address, :parent_id => :parent_id } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol hash map, but specifying column mismatches" do
|
||||
let(:update_columns){ { :title => :author_email_address, :author_email_address => :title, :parent_id => :parent_id } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned_with_hash_mappings
|
||||
should_update_foreign_keys
|
||||
end
|
||||
end
|
||||
|
||||
context "given array of model instances with :validation checks turned off" do
|
||||
macro(:perform_import) do
|
||||
macro(:perform_import) do |*opts|
|
||||
@topic.title = "Book - 2nd Edition"
|
||||
@topic.author_name = "Author Should Not Change"
|
||||
@topic.author_email_address = "johndoe@example.com"
|
||||
@topic.parent_id = 57
|
||||
Topic.import [@topic], :on_duplicate_key_update => update_columns, :validate => false
|
||||
Topic.import [@topic], opts.extract_options!.merge(:on_duplicate_key_update => update_columns, :validate => false)
|
||||
end
|
||||
|
||||
setup do
|
||||
|
@ -97,44 +80,38 @@ describe "#import with :on_duplicate_key_update option (mysql specific functiona
|
|||
|
||||
context "using string column names" do
|
||||
let(:update_columns){ [ "title", "author_email_address", "parent_id" ] }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol column names" do
|
||||
let(:update_columns){ [ :title, :author_email_address, :parent_id ] }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using string hash map" do
|
||||
let(:update_columns){ { "title" => "title", "author_email_address" => "author_email_address", "parent_id" => "parent_id" } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using string hash map, but specifying column mismatches" do
|
||||
let(:update_columns){ { "title" => "author_email_address", "author_email_address" => "title", "parent_id" => "parent_id" } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned_with_hash_mappings
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol hash map" do
|
||||
let(:update_columns){ { :title => :title, :author_email_address => :author_email_address, :parent_id => :parent_id } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned
|
||||
should_update_foreign_keys
|
||||
end
|
||||
|
||||
context "using symbol hash map, but specifying column mismatches" do
|
||||
let(:update_columns){ { :title => :author_email_address, :author_email_address => :title, :parent_id => :parent_id } }
|
||||
should_not_update_fields_not_mentioned
|
||||
should_support_on_duplicate_key_update
|
||||
should_update_fields_mentioned_with_hash_mappings
|
||||
should_update_foreign_keys
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,7 +23,9 @@ ActiveRecord::Schema.define do
|
|||
t.column :parent_id, :integer
|
||||
t.column :type, :string
|
||||
t.column :created_at, :datetime
|
||||
t.column :created_on, :datetime
|
||||
t.column :updated_at, :datetime
|
||||
t.column :updated_on, :datetime
|
||||
end
|
||||
|
||||
create_table :projects, :force=>true do |t|
|
||||
|
|
55
test/support/mysql/assertions.rb
Normal file
55
test/support/mysql/assertions.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
class ActiveSupport::TestCase
|
||||
module MySQLAssertions
|
||||
def self.extended(klass)
|
||||
klass.instance_eval do
|
||||
assertion(:should_not_update_created_at_on_timestamp_columns) do
|
||||
Delorean.time_travel_to("5 minutes from now") do
|
||||
perform_import
|
||||
assert_equal @topic.created_at.to_i, updated_topic.created_at.to_i
|
||||
assert_equal @topic.created_on.to_i, updated_topic.created_on.to_i
|
||||
end
|
||||
end
|
||||
|
||||
assertion(:should_update_updated_at_on_timestamp_columns) do
|
||||
time = Chronic.parse("5 minutes from now")
|
||||
Delorean.time_travel_to(time) do
|
||||
perform_import
|
||||
assert_equal time.to_i, updated_topic.updated_at.to_i
|
||||
assert_equal time.to_i, updated_topic.updated_on.to_i
|
||||
end
|
||||
end
|
||||
|
||||
assertion(:should_not_update_timestamps) do
|
||||
Delorean.time_travel_to("5 minutes from now") do
|
||||
perform_import :timestamps => false
|
||||
assert_equal @topic.created_at.to_i, updated_topic.created_at.to_i
|
||||
assert_equal @topic.created_on.to_i, updated_topic.created_on.to_i
|
||||
assert_equal @topic.updated_at.to_i, updated_topic.updated_at.to_i
|
||||
assert_equal @topic.updated_on.to_i, updated_topic.updated_on.to_i
|
||||
end
|
||||
end
|
||||
|
||||
assertion(:should_not_update_fields_not_mentioned) do
|
||||
assert_equal "John Doe", updated_topic.author_name
|
||||
end
|
||||
|
||||
assertion(:should_update_fields_mentioned) do
|
||||
perform_import
|
||||
assert_equal "Book - 2nd Edition", updated_topic.title
|
||||
assert_equal "johndoe@example.com", updated_topic.author_email_address
|
||||
end
|
||||
|
||||
assertion(:should_update_fields_mentioned_with_hash_mappings) do
|
||||
perform_import
|
||||
assert_equal "johndoe@example.com", updated_topic.title
|
||||
assert_equal "Book - 2nd Edition", updated_topic.author_email_address
|
||||
end
|
||||
|
||||
assertion(:should_update_foreign_keys) do
|
||||
perform_import
|
||||
assert_equal 57, updated_topic.parent_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,6 +31,13 @@ class ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def asssertion_group(name, &block)
|
||||
mc = class << self ; self ; end
|
||||
mc.class_eval do
|
||||
define_method(name, &block)
|
||||
end
|
||||
end
|
||||
|
||||
def macro(name, &block)
|
||||
class_eval do
|
||||
define_method(name, &block)
|
||||
|
@ -40,11 +47,20 @@ class ActiveSupport::TestCase
|
|||
def describe(description, toplevel=nil, &blk)
|
||||
text = toplevel ? description : "#{name} #{description}"
|
||||
klass = Class.new(self)
|
||||
|
||||
klass.class_eval <<-RUBY_EVAL
|
||||
def self.name
|
||||
"#{text}"
|
||||
end
|
||||
RUBY_EVAL
|
||||
|
||||
# do not inherit test methods from the superclass
|
||||
klass.class_eval do
|
||||
instance_methods.grep(/^test.+/) do |method|
|
||||
undef_method method
|
||||
end
|
||||
end
|
||||
|
||||
klass.instance_eval &blk
|
||||
end
|
||||
alias_method :context, :describe
|
||||
|
|
Loading…
Reference in a new issue