require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') TestCaseRoot = Class.new(Test::Unit::TestCase) TestCaseChild = Class.new(TestCaseRoot) TestCaseSibling = Class.new(TestCaseRoot) TestCaseGrandchild = Class.new(TestCaseChild) DatasetOne = Class.new(Dataset::Base) DatasetTwo = Class.new(Dataset::Base) describe Dataset::Session do before do @database = Dataset::Database::Sqlite3.new({:database => SQLITE_DATABASE}, "#{SPEC_ROOT}/tmp") @session = Dataset::Session.new(@database) end describe 'dataset associations' do it 'should allow the addition of datasets for a test' do @session.add_dataset TestCaseRoot, DatasetOne @session.datasets_for(TestCaseRoot).should == [DatasetOne] @session.add_dataset TestCaseRoot, DatasetTwo @session.datasets_for(TestCaseRoot).should == [DatasetOne, DatasetTwo] @session.add_dataset TestCaseRoot, DatasetOne @session.datasets_for(TestCaseRoot).should == [DatasetOne, DatasetTwo] end it 'should combine datasets from test superclasses into subclasses' do @session.add_dataset TestCaseRoot, DatasetOne @session.add_dataset TestCaseChild, DatasetTwo @session.add_dataset TestCaseChild, DatasetOne @session.datasets_for(TestCaseChild).should == [DatasetOne, DatasetTwo] @session.datasets_for(TestCaseGrandchild).should == [DatasetOne, DatasetTwo] end it 'should include those that a dataset declares it uses' do dataset_one = Class.new(Dataset::Base) do uses DatasetTwo end dataset_two = Class.new(Dataset::Base) do uses dataset_one, DatasetOne end @session.add_dataset TestCaseRoot, dataset_two @session.add_dataset TestCaseChild, DatasetTwo @session.datasets_for(TestCaseChild).should == [DatasetTwo, dataset_one, DatasetOne, dataset_two] @session.datasets_for(TestCaseGrandchild).should == [DatasetTwo, dataset_one, DatasetOne, dataset_two] end it 'should accept a dataset name' do @session.add_dataset TestCaseRoot, :dataset_one @session.datasets_for(TestCaseRoot).should == [DatasetOne] dataset = Class.new(Dataset::Base) do uses :dataset_two, :dataset_one end @session.add_dataset TestCaseChild, dataset @session.datasets_for(TestCaseChild).should == [DatasetOne, DatasetTwo, dataset] end end describe 'dataset loading' do it 'should clear the database on first load' do @database.should_receive(:clear).once() dataset_one = Class.new(Dataset::Base) dataset_two = Class.new(Dataset::Base) @session.add_dataset TestCaseRoot, dataset_one @session.add_dataset TestCaseChild, dataset_one @session.load_datasets_for(TestCaseRoot) @session.load_datasets_for(TestCaseChild) end it 'should clear the database on loads where there is no subset' do @database.should_receive(:clear).twice() dataset_one = Class.new(Dataset::Base) dataset_two = Class.new(Dataset::Base) @session.add_dataset TestCaseChild, dataset_one @session.add_dataset TestCaseSibling, dataset_two @session.load_datasets_for(TestCaseChild) @session.load_datasets_for(TestCaseSibling) end it 'should not capture the dataset if it is the same as the last loaded' do @database.should_not_receive(:capture) dataset_one = Class.new(Dataset::Base) @session.add_dataset TestCaseRoot, dataset_one @session.load_datasets_for(TestCaseRoot) @session.load_datasets_for(TestCaseChild) @session.load_datasets_for(TestCaseSibling) end it 'should happen in the order declared' do load_order = [] dataset_one = Class.new(Dataset::Base) { define_method :load do load_order << self.class end } dataset_two = Class.new(Dataset::Base) { define_method :load do load_order << self.class end } @session.add_dataset TestCaseRoot, dataset_two @session.add_dataset TestCaseRoot, dataset_one @session.load_datasets_for TestCaseRoot load_order.should == [dataset_two, dataset_one] end it 'should install dataset helpers into defining dataset, and not cross into other datasets' do dataset_instances = [] dataset_one = Class.new(Dataset::Base) { helpers do def helper_one; end end define_method :load do dataset_instances << self end } dataset_two = Class.new(Dataset::Base) { helpers do def helper_two; end end define_method :load do dataset_instances << self end } @session.add_dataset TestCaseRoot, dataset_one @session.add_dataset TestCaseRoot, dataset_two @session.load_datasets_for TestCaseRoot dataset_instances.first.should respond_to(:helper_one) dataset_instances.first.should_not respond_to(:helper_two) dataset_instances.last.should_not respond_to(:helper_one) dataset_instances.last.should respond_to(:helper_two) dataset_one.instance_methods.should include('helper_one') dataset_one.instance_methods.should_not include('helper_two') dataset_two.instance_methods.should_not include('helper_one') dataset_two.instance_methods.should include('helper_two') end it 'should install dataset helpers into datasets that are using another' do dataset_instances = [] dataset_one = Class.new(Dataset::Base) { helpers do def helper_one; end end define_method :load do dataset_instances << self end } dataset_two = Class.new(Dataset::Base) { uses dataset_one helpers do def helper_two; end end define_method :load do dataset_instances << self end } @session.add_dataset TestCaseRoot, dataset_one @session.add_dataset TestCaseRoot, dataset_two @session.load_datasets_for TestCaseRoot dataset_instances.first.should respond_to(:helper_one) dataset_instances.first.should_not respond_to(:helper_two) dataset_instances.last.should respond_to(:helper_one) dataset_instances.last.should respond_to(:helper_two) dataset_one.instance_methods.should include('helper_one') dataset_one.instance_methods.should_not include('helper_two') dataset_two.instance_methods.should_not include('helper_one') dataset_two.instance_methods.should include('helper_two') end it 'should happen only once per test in a hierarchy' do load_count = 0 dataset = Class.new(Dataset::Base) { define_method :load do load_count += 1 end } @session.add_dataset TestCaseRoot, dataset @session.load_datasets_for TestCaseRoot load_count.should == 1 @session.load_datasets_for TestCaseRoot load_count.should == 1 @session.load_datasets_for TestCaseChild load_count.should == 1 end it 'should capture the existing data before loading a superset, restoring the subset before a peer runs' do dataset_one_load_count = 0 dataset_one = Class.new(Dataset::Base) do define_method :load do dataset_one_load_count += 1 Thing.create! end end dataset_two_load_count = 0 dataset_two = Class.new(Dataset::Base) do define_method :load do dataset_two_load_count += 1 Place.create! end end @session.add_dataset TestCaseRoot, dataset_one @session.add_dataset TestCaseChild, dataset_two @session.load_datasets_for TestCaseRoot dataset_one_load_count.should == 1 dataset_two_load_count.should == 0 Thing.count.should == 1 Place.count.should == 0 @session.load_datasets_for TestCaseChild dataset_one_load_count.should == 1 dataset_two_load_count.should == 1 Thing.count.should == 1 Place.count.should == 1 @session.load_datasets_for TestCaseSibling dataset_one_load_count.should == 1 dataset_two_load_count.should == 1 Thing.count.should == 1 Place.count.should == 0 end it 'should install the record methods into the datasets' do instance_of_dataset_one = nil dataset_one = Class.new(Dataset::Base) do define_method :load do instance_of_dataset_one = self end end @session.add_dataset TestCaseRoot, dataset_one @session.load_datasets_for TestCaseRoot instance_of_dataset_one.should_not be_nil instance_of_dataset_one.should respond_to(:create_record) instance_of_dataset_one.should respond_to(:create_model) instance_of_dataset_one.should respond_to(:name_model) instance_of_dataset_one.should respond_to(:find_model) instance_of_dataset_one.should respond_to(:find_id) end it 'should install the instance loader methods into the dataset instance' do instance_of_dataset_one = nil dataset_one = Class.new(Dataset::Base) do define_method :load do create_record(Thing) instance_of_dataset_one = self end end @session.add_dataset TestCaseRoot, dataset_one @session.load_datasets_for TestCaseRoot instance_of_dataset_one.should respond_to(:things) end it 'should copy instance variables assigned in dataset blocks to binding' do @session.add_dataset(TestCaseRoot, Class.new(Dataset::Block) { define_method :doload do @myvar = 'Hello' end }) load = @session.load_datasets_for(TestCaseRoot) load.dataset_binding.block_variables['@myvar'].should == 'Hello' end end describe 'bindings' do it 'should be created for each dataset load, wrapping the outer binding' do binding_one = Dataset::SessionBinding.new(@database) binding_two = Dataset::SessionBinding.new(binding_one) binding_three = Dataset::SessionBinding.new(binding_one) Dataset::SessionBinding.should_receive(:new).with(@database).and_return(binding_one) Dataset::SessionBinding.should_receive(:new).with(binding_one).twice().and_return(binding_two) dataset_one = Class.new(Dataset::Base) { define_method :load do; end } dataset_two = Class.new(Dataset::Base) { define_method :load do; end } @session.add_dataset TestCaseRoot, dataset_one @session.add_dataset TestCaseChild, dataset_two @session.load_datasets_for TestCaseRoot @session.load_datasets_for TestCaseChild @session.load_datasets_for TestCaseSibling end end end