tc_active_record.rb [plain text]
require 'test/unit'
begin
begin
require 'rubygems'
rescue LoadError
end
require 'osx/active_record'
require 'sqlite3'
class Object
def __stub(mname, *return_values)
@return_values = return_values
instance_eval %{
def self.#{mname}
return *@return_values
end
}
end
end
class FakePointer
attr_reader :value
def initialize; @value = nil; end
def assign(value); @value = value; end
end
ActiveRecord::Base.establish_connection({
:adapter => 'sqlite3',
:dbfile => ':memory:'
})
ActiveRecord::Migration.verbose = false
module ARTestHelper
def setup_db
ActiveRecord::Schema.define do
create_table :mailboxes do |t|
t.column :title, :string, :default => 'title'
end
create_table :emails do |t|
t.column :mailbox_id, :integer
t.column :address, :string, :default => "test@test.com"
t.column :subject, :string, :default => "test subject"
t.column :body, :text
t.column :updated_at, :datetime
end
end
end
def teardown_db
ActiveRecord::Base.connection.tables.each do |table|
ActiveRecord::Base.connection.drop_table(table)
end
end
def setup; setup_db; end
def teardown; teardown_db; end
def assert_difference(eval_string, difference)
initial_value = eval(eval_string)
yield
assert_equal (initial_value + difference), eval(eval_string)
end
def assert_no_difference(eval_string)
initial_value = eval(eval_string)
yield
assert_equal initial_value, eval(eval_string)
end
end
class Mailbox < ActiveRecord::Base
has_many :emails
validates_presence_of :title
end
class Email < ActiveRecord::Base
belongs_to :mailbox
end
class EmailProxy < OSX::ActiveRecordProxy
on_get :body do |content|
content ||= 'empty'
OSX::NSAttributedString.alloc.initWithString(content)
end
on_get :subject, :return => [OSX::NSAttributedString, :initWithString]
on_get :address, :call => :nsattributed_string_from_address
def nsattributed_string_from_address(address)
address ||= 'empty'
OSX::NSAttributedString.alloc.initWithString(address)
end
end
class TC_ActiveRecordClassExtensions < Test::Unit::TestCase
include ARTestHelper
def setup
setup_db
@mailbox = Mailbox.create({'title' => 'foo'})
end
def test_array_of_activerecords_to_proxies
assert_kind_of MailboxProxy, Mailbox.find(:all).to_activerecord_proxies.first
end
def test_array_of_proxies_to_original_activerecords
assert_kind_of Mailbox, Mailbox.find(:all).to_activerecord_proxies.original_records.first
end
def test_automatically_creates_a_proxy
assert Object.const_defined?('MailboxProxy')
end
def test_activerecord_to_proxy
proxy = Mailbox.find(:first).to_activerecord_proxy
assert_kind_of MailboxProxy, proxy
assert_equal @mailbox, proxy.to_activerecord
end
def test_namespaced_activerecord_base_subclassing
assert_nothing_raised NameError do
eval "module TestNamespace; class BaseSubclass < ActiveRecord::Base; end; end"
end
end
end
class TC_ActiveRecordSetController < Test::Unit::TestCase
include ARTestHelper
def setup
setup_db
3.times { Mailbox.create }
@controller = OSX::ActiveRecordSetController.alloc.init
@controller.objectClass = MailboxProxy
@controller.content = MailboxProxy.find(:all)
end
def test_should_instantiate_and_save_a_record_on_newObject
assert_difference('Mailbox.count', +1) do
@controller.newObject
end
end
def test_should_destroy_a_record_on_remove
@controller.__stub(:selectedObjects, [MailboxProxy.find(:first)].to_ns)
assert_difference('Mailbox.count', -1) do
@controller.remove(nil)
end
end
def test_should_destroy_multiple_records_on_remove
@controller.__stub(:selectedObjects, MailboxProxy.find(:all, :limit => 2).to_ns)
assert_difference('Mailbox.count', -2) do
@controller.remove(nil)
end
end
end
class TC_BelongsToActiveRecordSetController < Test::Unit::TestCase
include ARTestHelper
def setup
setup_db
@controller = OSX::BelongsToActiveRecordSetController.alloc.init
@controller.objectClass = MailboxProxy
@controller.content = MailboxProxy.find(:all)
end
def test_should_instantiate_but_not_save_a_record_on_newObject
assert_no_difference('Mailbox.count') do
@controller.newObject
end
end
end
class TC_ActiveRecordTableView < Test::Unit::TestCase
include ARTestHelper
def setup
setup_db
@tableview = OSX::ActiveRecordTableView.alloc.init
@recordset_controller = OSX::ActiveRecordSetController.alloc.init
end
def test_should_raise_argument_errors_for_missing_arguments_when_trying_to_scaffold
assert_raises ArgumentError do
@tableview.scaffold_columns_for :model => nil, :bind_to => @recordset_controller
end
assert_raises ArgumentError do
@tableview.scaffold_columns_for :model => Email, :bind_to => nil
end
end
end
class TC_ActiveRecordProxy < Test::Unit::TestCase
include ARTestHelper
def setup
setup_db
mailbox = Mailbox.create('title' => 'foo')
mailbox.emails << Email.new
@email_proxy = EmailProxy.find(:first)
end
def teardown
teardown_db
end
def test_proxy_init_should_not_create_a_new_record
assert_no_difference("Mailbox.count") do
MailboxProxy.alloc.init
end
end
def test_proxy_initWithRecord
mailbox = Mailbox.new({ 'title' => 'initWithRecord' })
mailbox.save
before = Mailbox.count
proxy = MailboxProxy.alloc.initWithRecord(mailbox)
assert Mailbox.count == before
assert_equal proxy.to_activerecord, mailbox
end
def test_proxy_initWithAttributes
assert_difference('Mailbox.count', +1) do
proxy = MailboxProxy.alloc.initWithAttributes({ 'title' => 'initWithAttributes' })
assert_equal 'initWithAttributes', proxy.to_activerecord.title
end
end
def test_should_always_return_the_same_cached_proxy_for_a_record_object
proxy1 = @email_proxy.mailbox.to_activerecord_proxy
proxy2 = @email_proxy.mailbox.to_activerecord_proxy
assert_equal proxy1.object_id, proxy2.object_id
end
def test_should_only_define_all_the_proxy_methods_once
temp_class_eval_email_proxy_class do
assert_difference("EmailProxy.instance_variable_get(:@test_counter)", +1) do
2.times { EmailProxy.find(:first) }
end
end
end
def test_should_return_a_proxy_when_requesting_a_belongs_to_associated_record
assert_kind_of OSX::ActiveRecordProxy, @email_proxy.mailbox
end
def test_should_be_able_to_compare_proxies
id = Mailbox.create(:title => 'compare').id
m1 = MailboxProxy.find(id)
m2 = MailboxProxy.find(id)
assert_equal m1, m2
assert_not_equal m1, 'foo'
end
def test_generated_instance_methods_on_proxy
mailbox = MailboxProxy.find(:first)
mailbox.title = 'baz'
assert_equal 'baz', mailbox['title']
mailbox['title'] = 'bar'
assert_equal 'bar', mailbox.title
assert_raises OSX::OCMessageSendException do
mailbox.pretty_sure_this_one_does_not_exist = 'foo'
end
end
def test_methods_from_record
mailbox = Mailbox.find(:first)
proxy = mailbox.to_activerecord_proxy
assert_equal mailbox.methods, proxy.record_methods
end
def test_proxy_is_association?
proxy = Mailbox.find(:first).to_activerecord_proxy
assert proxy.is_association?('emails')
assert !proxy.is_association?('title')
end
def test_proxy_method_forwarding
mailbox = MailboxProxy.find(:first)
assert_equal mailbox.title, Mailbox.find(:first).title
end
def test_proxy_set_and_get_value_for_key
mailbox = MailboxProxy.alloc.initWithAttributes({'title' => 'bla'})
mailbox.setValue_forKey( [EmailProxy.alloc.initWithAttributes({'address' => 'bla@example.com', 'subject' => nil, 'body' => 'foobar'})], 'emails' )
assert_equal 'bla', mailbox.valueForKey('title')
assert_equal 'foobar', mailbox.valueForKey('emails')[0].valueForKey('body').string
assert_kind_of OSX::NSAttributedString, mailbox.valueForKey('emails')[0].valueForKey('body')
assert_kind_of OSX::NSAttributedString, mailbox.valueForKey('emails')[0].valueForKey('subject')
assert_equal '', mailbox.valueForKey('emails')[0].valueForKey('subject').string
assert_kind_of OSX::NSAttributedString, mailbox.valueForKey('emails')[0].valueForKey('address')
end
def test_proxy_validate_value_for_key_with_error
mailbox = Mailbox.find(:first).to_activerecord_proxy
before = mailbox.title
pointer = FakePointer.new
result = mailbox.validateValue_forKeyPath_error([''], 'title', pointer)
assert result == false
assert_equal before, mailbox.title
assert_kind_of OSX::NSError, pointer.value
assert_equal "Mailbox title can't be blank\n", pointer.value.userInfo[OSX::NSLocalizedDescriptionKey]
end
def test_proxy_to_model_class
assert_equal Mailbox, MailboxProxy.model_class
end
def test_find_first
mailbox = Mailbox.find(:first)
proxy = MailboxProxy.find(:first)
assert_equal mailbox, proxy.original_record
end
def test_find_all
mailboxes = Mailbox.find(:all)
proxies = MailboxProxy.find(:all)
assert_equal mailboxes, proxies.original_records
end
def test_find_by
mailbox = Mailbox.find_by_title('foo')
proxy = MailboxProxy.find_by_title('foo')
assert_equal mailbox, proxy.original_record
end
private
def temp_class_eval_email_proxy_class
EmailProxy.class_eval do
@record_methods_defined = nil
@test_counter = 0
alias_method :original_define_record_methods!, :define_record_methods!
def define_record_methods!
original_define_record_methods!
self.class.instance_variable_set(:@test_counter, self.class.instance_variable_get(:@test_counter) + 1)
end
yield
alias_method :define_record_methods!, :original_define_record_methods!
end
end
end
rescue LoadError
$stderr.puts 'Skipping osx/active_record tests, you need to have active_record and sqlite3'
end