dataset 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +59 -0
- data/LICENSE +19 -0
- data/README +111 -0
- data/Rakefile +31 -0
- data/TODO +15 -0
- data/VERSION.yml +4 -0
- data/lib/dataset.rb +128 -0
- data/lib/dataset/base.rb +157 -0
- data/lib/dataset/collection.rb +19 -0
- data/lib/dataset/database/base.rb +30 -0
- data/lib/dataset/database/mysql.rb +34 -0
- data/lib/dataset/database/postgresql.rb +34 -0
- data/lib/dataset/database/sqlite3.rb +32 -0
- data/lib/dataset/extensions/cucumber.rb +20 -0
- data/lib/dataset/extensions/rspec.rb +21 -0
- data/lib/dataset/extensions/test_unit.rb +60 -0
- data/lib/dataset/instance_methods.rb +10 -0
- data/lib/dataset/load.rb +47 -0
- data/lib/dataset/record/fixture.rb +73 -0
- data/lib/dataset/record/meta.rb +66 -0
- data/lib/dataset/record/model.rb +50 -0
- data/lib/dataset/resolver.rb +110 -0
- data/lib/dataset/session.rb +51 -0
- data/lib/dataset/session_binding.rb +317 -0
- data/lib/dataset/version.rb +9 -0
- data/plugit/descriptor.rb +25 -0
- data/spec/dataset/cucumber_spec.rb +54 -0
- data/spec/dataset/database/base_spec.rb +21 -0
- data/spec/dataset/record/meta_spec.rb +14 -0
- data/spec/dataset/resolver_spec.rb +110 -0
- data/spec/dataset/rspec_spec.rb +133 -0
- data/spec/dataset/session_binding_spec.rb +198 -0
- data/spec/dataset/session_spec.rb +299 -0
- data/spec/dataset/test_unit_spec.rb +210 -0
- data/spec/fixtures/datasets/constant_not_defined.rb +0 -0
- data/spec/fixtures/datasets/ending_with_dataset.rb +2 -0
- data/spec/fixtures/datasets/exact_name.rb +2 -0
- data/spec/fixtures/datasets/not_a_dataset_base.rb +2 -0
- data/spec/fixtures/more_datasets/in_another_directory.rb +2 -0
- data/spec/models.rb +18 -0
- data/spec/schema.rb +26 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/stubs/mini_rails.rb +18 -0
- data/spec/stubs/test_help.rb +1 -0
- data/tasks/dataset.rake +19 -0
- metadata +120 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'plugit'
|
3
|
+
|
4
|
+
PLUGIT_ROOT = File.expand_path(File.dirname(__FILE__))
|
5
|
+
|
6
|
+
Plugit.describe do |dataset|
|
7
|
+
dataset.environments_root_path = "#{PLUGIT_ROOT}/environments"
|
8
|
+
vendor_directory = "#{PLUGIT_ROOT}/../vendor/plugins"
|
9
|
+
|
10
|
+
dataset.environment :default, 'Released versions of Rails and RSpec' do |env|
|
11
|
+
env.library :rails, :export => "git clone git://github.com/rails/rails.git" do |rails|
|
12
|
+
rails.after_update { `git fetch origin 2-3-stable:2-3-stable; git checkout 2-3-stable` }
|
13
|
+
rails.load_paths = %w{/activesupport/lib /activerecord/lib /actionpack/lib}
|
14
|
+
rails.requires = %w{active_support active_record active_record/fixtures action_controller action_view}
|
15
|
+
end
|
16
|
+
env.library :rspec, :export => "git clone git://github.com/dchelimsky/rspec.git" do |rspec|
|
17
|
+
rspec.after_update { `git checkout -b rspecrelease 1.1.12 && mkdir -p #{vendor_directory} && ln -nsf #{File.expand_path('.')} #{vendor_directory + '/rspec'}` }
|
18
|
+
rspec.requires = %w{spec}
|
19
|
+
end
|
20
|
+
env.library :cucumber, :export => "git clone git://github.com/aslakhellesoy/cucumber.git" do |cukes|
|
21
|
+
cukes.after_update { `git fetch origin master; git checkout v0.2.3.1` }
|
22
|
+
cukes.requires = %w{cucumber}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
$:.unshift(File.dirname(__FILE__) + '/../stubs')
|
4
|
+
require "mini_rails"
|
5
|
+
|
6
|
+
require 'cucumber/rails/world'
|
7
|
+
require 'cucumber/rails/rspec'
|
8
|
+
Cucumber::Rails::World.class_eval do
|
9
|
+
include Dataset
|
10
|
+
end
|
11
|
+
|
12
|
+
describe Cucumber::Rails::World do
|
13
|
+
|
14
|
+
it 'should have a dataset method' do
|
15
|
+
world = Class.new(Cucumber::Rails::World)
|
16
|
+
world.should respond_to(:dataset)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should load the dataset when the feature is run' do
|
20
|
+
load_count = 0
|
21
|
+
my_dataset = Class.new(Dataset::Base) do
|
22
|
+
define_method(:load) do
|
23
|
+
load_count += 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
step_mother = Object.new
|
28
|
+
step_mother.extend(Cucumber::StepMother)
|
29
|
+
$__cucumber_toplevel = step_mother
|
30
|
+
step_mother.World do |world|
|
31
|
+
world = Cucumber::Rails::World.new
|
32
|
+
world.class.dataset(my_dataset)
|
33
|
+
world
|
34
|
+
end
|
35
|
+
step_mother.Given /true is true/ do |n|
|
36
|
+
true.should == true
|
37
|
+
end
|
38
|
+
visitor = Cucumber::Ast::Visitor.new(step_mother)
|
39
|
+
|
40
|
+
scenario = Cucumber::Ast::Scenario.new(
|
41
|
+
background=nil,
|
42
|
+
comment=Cucumber::Ast::Comment.new(""),
|
43
|
+
tags=Cucumber::Ast::Tags.new(98, []),
|
44
|
+
line=99,
|
45
|
+
keyword="",
|
46
|
+
name="",
|
47
|
+
steps=[
|
48
|
+
Cucumber::Ast::Step.new(8, "Given", "true is true")
|
49
|
+
])
|
50
|
+
visitor.visit_feature_element(scenario)
|
51
|
+
|
52
|
+
load_count.should be(1)
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Dataset::Database::Base do
|
4
|
+
before do
|
5
|
+
@database = Dataset::Database::Base.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should clear the tables of all AR classes' do
|
9
|
+
Place.create!
|
10
|
+
Thing.create!
|
11
|
+
@database.clear
|
12
|
+
Place.count.should be(0)
|
13
|
+
Thing.count.should be(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should not clear the "schema_migrations" table' do
|
17
|
+
ActiveRecord::Base.connection.insert("INSERT INTO #{ActiveRecord::Migrator.schema_migrations_table_name} (version) VALUES ('testing123')")
|
18
|
+
@database.clear
|
19
|
+
ActiveRecord::Base.connection.select_one("SELECT version FROM #{ActiveRecord::Migrator.schema_migrations_table_name} WHERE version = 'testing123'").should_not be_blank
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
class MThingy
|
4
|
+
class NThingy
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Dataset::Record::Meta, 'finder name' do
|
9
|
+
it 'should collapse single character followed by underscore to just the single character' do
|
10
|
+
@meta = Dataset::Record::Meta.new(Place)
|
11
|
+
@meta.finder_name(MThingy).should == 'mthingy'
|
12
|
+
@meta.finder_name(MThingy::NThingy).should == 'mthingy_nthingy'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
ResolveThis = Class.new(Dataset::Base)
|
4
|
+
ResolveDataset = Class.new(Dataset::Base)
|
5
|
+
SomeModelNotDs = Class.new
|
6
|
+
SomeModelNotDsDataset = Class.new(Dataset::Base)
|
7
|
+
NotADataset = Class.new
|
8
|
+
TheModule = Module.new
|
9
|
+
TheModuleDataset = Class.new(Dataset::Base)
|
10
|
+
|
11
|
+
describe Dataset::Resolver do
|
12
|
+
before do
|
13
|
+
@resolver = Dataset::Resolver.new
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should skip modules' do
|
17
|
+
@resolver.resolve(:the_module).should == TheModuleDataset
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should find simply classified' do
|
21
|
+
@resolver.resolve(:resolve_this).should == ResolveThis
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should find ending with Dataset' do
|
25
|
+
@resolver.resolve(:resolve).should == ResolveDataset
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should keep looking if first try is not a dataset' do
|
29
|
+
dataset = @resolver.resolve(:some_model_not_ds)
|
30
|
+
dataset.should_not be(SomeModelNotDs)
|
31
|
+
dataset.should == SomeModelNotDsDataset
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should indicate when found class is not a dataset' do
|
35
|
+
lambda do
|
36
|
+
@resolver.resolve(:not_a_dataset)
|
37
|
+
end.should raise_error(
|
38
|
+
Dataset::DatasetNotFound,
|
39
|
+
"Found a class 'NotADataset', but it does not subclass 'Dataset::Base'."
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should indicate that it could not find a dataset' do
|
44
|
+
lambda do
|
45
|
+
@resolver.resolve(:undefined)
|
46
|
+
end.should raise_error(
|
47
|
+
Dataset::DatasetNotFound,
|
48
|
+
"Could not find a dataset 'Undefined' or 'UndefinedDataset'."
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe Dataset::DirectoryResolver do
|
54
|
+
before do
|
55
|
+
@resolver = Dataset::DirectoryResolver.new(SPEC_ROOT + '/fixtures/datasets')
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should not look for a file if the constant is already defined' do
|
59
|
+
@resolver.resolve(:resolve).should be(ResolveDataset)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should find file with exact name match' do
|
63
|
+
defined?(ExactName).should be_nil
|
64
|
+
dataset = @resolver.resolve(:exact_name)
|
65
|
+
defined?(ExactName).should == 'constant'
|
66
|
+
dataset.should == ExactName
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should find file with name ending in _dataset' do
|
70
|
+
defined?(EndingWithDataset).should be_nil
|
71
|
+
dataset = @resolver.resolve(:ending_with)
|
72
|
+
defined?(EndingWithDataset).should == 'constant'
|
73
|
+
dataset.should == EndingWithDataset
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should indicate that it could not find a dataset file' do
|
77
|
+
lambda do
|
78
|
+
@resolver.resolve(:undefined)
|
79
|
+
end.should raise_error(
|
80
|
+
Dataset::DatasetNotFound,
|
81
|
+
%(Could not find a dataset file in ["#{SPEC_ROOT + '/fixtures/datasets'}"] having the name 'undefined.rb' or 'undefined_dataset.rb'.)
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should indicate when it finds a file, but the constant is not defined after loading the file' do
|
86
|
+
lambda do
|
87
|
+
@resolver.resolve(:constant_not_defined)
|
88
|
+
end.should raise_error(
|
89
|
+
Dataset::DatasetNotFound,
|
90
|
+
"Found the dataset file '#{SPEC_ROOT + '/fixtures/datasets/constant_not_defined.rb'}', but it did not define a dataset 'ConstantNotDefined' or 'ConstantNotDefinedDataset'."
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should indicate when it finds a file, but the constant defined is not a subclass of Dataset::Base' do
|
95
|
+
lambda do
|
96
|
+
@resolver.resolve(:not_a_dataset_base)
|
97
|
+
end.should raise_error(
|
98
|
+
Dataset::DatasetNotFound,
|
99
|
+
"Found the dataset file '#{SPEC_ROOT + '/fixtures/datasets/not_a_dataset_base.rb'}' and a class 'NotADatasetBase', but it does not subclass 'Dataset::Base'."
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should support adding multiple directories' do
|
104
|
+
@resolver << (SPEC_ROOT + '/fixtures/more_datasets')
|
105
|
+
defined?(InAnotherDirectoryDataset).should be_nil
|
106
|
+
dataset = @resolver.resolve(:in_another_directory)
|
107
|
+
defined?(InAnotherDirectoryDataset).should == 'constant'
|
108
|
+
dataset.should == InAnotherDirectoryDataset
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
class Spec::Example::ExampleGroup
|
4
|
+
include Dataset
|
5
|
+
end
|
6
|
+
|
7
|
+
describe Spec::Example::ExampleGroup do
|
8
|
+
with_sandboxed_options do
|
9
|
+
it 'should have a dataset method' do
|
10
|
+
group = Class.new(Spec::Example::ExampleGroup)
|
11
|
+
group.should respond_to(:dataset)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should load the dataset when the group is run' do
|
15
|
+
load_count = 0
|
16
|
+
dataset = Class.new(Dataset::Base) do
|
17
|
+
define_method(:load) do
|
18
|
+
load_count += 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
group = Class.new(Spec::Example::ExampleGroup) do
|
23
|
+
self.dataset(dataset)
|
24
|
+
it('one') {}
|
25
|
+
it('two') {}
|
26
|
+
end
|
27
|
+
|
28
|
+
group.run options
|
29
|
+
load_count.should be(1)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should load datasets in nested groups' do
|
33
|
+
dataset_one = Class.new(Dataset::Base) do
|
34
|
+
define_method(:load) do
|
35
|
+
Thing.create!
|
36
|
+
end
|
37
|
+
end
|
38
|
+
dataset_two = Class.new(Dataset::Base) do
|
39
|
+
define_method(:load) do
|
40
|
+
Place.create!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
group = Class.new(Spec::Example::ExampleGroup) do
|
45
|
+
dataset(dataset_one)
|
46
|
+
it('one') {}
|
47
|
+
end
|
48
|
+
group_child = Class.new(group) do
|
49
|
+
dataset(dataset_two)
|
50
|
+
it('two') {}
|
51
|
+
end
|
52
|
+
|
53
|
+
group.run options
|
54
|
+
Thing.count.should be(1)
|
55
|
+
Place.count.should be(0)
|
56
|
+
|
57
|
+
group_child.run options
|
58
|
+
Thing.count.should be(1)
|
59
|
+
Place.count.should be(1)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should expose data reading methods from dataset binding to the test methods through the group instances' do
|
63
|
+
created_model = nil
|
64
|
+
dataset = Class.new(Dataset::Base) do
|
65
|
+
define_method(:load) do
|
66
|
+
created_model = create_model(Thing, :dataset_thing)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
found_in_before_all, dataset_thing_in_example = nil
|
71
|
+
created_in_before_all, before_all_thing_in_example = nil
|
72
|
+
created_in_example = nil
|
73
|
+
group = Class.new(Spec::Example::ExampleGroup) do
|
74
|
+
self.dataset(dataset)
|
75
|
+
before(:all) do
|
76
|
+
found_in_before_all = things(:dataset_thing)
|
77
|
+
created_in_before_all = create_model(Thing, :before_all_thing)
|
78
|
+
end
|
79
|
+
it 'one' do
|
80
|
+
dataset_thing_in_example = things(:dataset_thing)
|
81
|
+
before_all_thing_in_example = things(:before_all_thing)
|
82
|
+
created_in_example = create_model(Thing)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
group.run options
|
87
|
+
group.should_not respond_to(:things)
|
88
|
+
|
89
|
+
dataset_thing_in_example.should_not be_nil
|
90
|
+
dataset_thing_in_example.should == created_model
|
91
|
+
|
92
|
+
found_in_before_all.should_not be_nil
|
93
|
+
found_in_before_all.should == created_model
|
94
|
+
|
95
|
+
created_in_before_all.should_not be_nil
|
96
|
+
before_all_thing_in_example.should == created_in_before_all
|
97
|
+
|
98
|
+
created_in_example.should_not be_nil
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should expose dataset helper methods to the test methods through the group instances' do
|
102
|
+
dataset_one = Class.new(Dataset::Base) do
|
103
|
+
helpers do
|
104
|
+
def helper_one; end
|
105
|
+
end
|
106
|
+
def load; end
|
107
|
+
end
|
108
|
+
dataset_two = Class.new(Dataset::Base) do
|
109
|
+
uses dataset_one
|
110
|
+
helpers do
|
111
|
+
def helper_two; end
|
112
|
+
end
|
113
|
+
def load; end
|
114
|
+
end
|
115
|
+
|
116
|
+
group = Class.new(Spec::Example::ExampleGroup) do
|
117
|
+
self.dataset(dataset_two)
|
118
|
+
before(:all) do
|
119
|
+
self.should respond_to(:helper_one)
|
120
|
+
self.should respond_to(:helper_two)
|
121
|
+
end
|
122
|
+
it 'one' do
|
123
|
+
self.should respond_to(:helper_one)
|
124
|
+
self.should respond_to(:helper_two)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
group.run options
|
129
|
+
group.should_not respond_to(:helper_one)
|
130
|
+
group.should_not respond_to(:helper_two)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,198 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
describe Dataset::SessionBinding do
|
4
|
+
before :all do
|
5
|
+
@database = Dataset::Database::Sqlite3.new({:database => SQLITE_DATABASE}, "#{SPEC_ROOT}/tmp")
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@database.clear
|
10
|
+
@binding = Dataset::SessionBinding.new(@database)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should support direct record inserts like classic fixtures' do
|
14
|
+
Thing.should_not_receive :new
|
15
|
+
lambda do
|
16
|
+
return_value = @binding.create_record Thing
|
17
|
+
return_value.should be_kind_of(Integer)
|
18
|
+
end.should change(Thing, :count).by(1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should support creating records by instantiating the record class so callbacks work' do
|
22
|
+
thing = Thing.new
|
23
|
+
Thing.should_receive(:new).and_return(thing)
|
24
|
+
lambda do
|
25
|
+
return_value = @binding.create_model Thing
|
26
|
+
return_value.should be_kind_of(Thing)
|
27
|
+
end.should change(Thing, :count).by(1)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should provide itself to the instance loaders' do
|
31
|
+
anything = Object.new
|
32
|
+
anything.extend @binding.model_finders
|
33
|
+
anything.dataset_session_binding.should == @binding
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'create_record' do
|
37
|
+
it 'should accept raw attributes for the insert' do
|
38
|
+
@binding.create_record Thing, :name => 'my thing'
|
39
|
+
Thing.last.name.should == 'my thing'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should optionally accept a symbolic name for later lookup' do
|
43
|
+
id = @binding.create_record Thing, :my_thing, :name => 'my thing'
|
44
|
+
@binding.find_model(Thing, :my_thing).id.should == id
|
45
|
+
@binding.find_id(Thing, :my_thing).should == id
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should auto-assign _at and _on columns with their respective time types' do
|
49
|
+
@binding.create_record Note
|
50
|
+
Note.last.created_at.should_not be_nil
|
51
|
+
Note.last.updated_at.should_not be_nil
|
52
|
+
|
53
|
+
@binding.create_record Thing
|
54
|
+
Thing.last.created_on.should_not be_nil
|
55
|
+
Thing.last.updated_on.should_not be_nil
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should support belongs_to associations using symbolic name of associated type' do
|
59
|
+
person_id = @binding.create_record Person, :person
|
60
|
+
@binding.create_record Note, :note, :person => :person
|
61
|
+
Note.last.person_id.should == person_id
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'create_model' do
|
66
|
+
it 'should accept raw attributes for the insert' do
|
67
|
+
@binding.create_model Thing, :name => 'my thing'
|
68
|
+
Thing.last.name.should == 'my thing'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should optionally accept a symbolic name for later lookup' do
|
72
|
+
thing = @binding.create_model Thing, :my_thing, :name => 'my thing'
|
73
|
+
@binding.find_model(Thing, :my_thing).should == thing
|
74
|
+
@binding.find_id(Thing, :my_thing).should == thing.id
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should bypass mass assignment restrictions' do
|
78
|
+
person = @binding.create_model Person, :first_name => 'Adam', :last_name => 'Williams'
|
79
|
+
person.last_name.should == 'Williams'
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
it 'should support belongs_to associations using symbolic name of associated type' do
|
84
|
+
person_id = @binding.create_record Person, :person
|
85
|
+
@binding.create_model Note, :note, :person => :person
|
86
|
+
Note.last.person_id.should == person_id
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'model finders' do
|
91
|
+
before do
|
92
|
+
@context = Object.new
|
93
|
+
@context.extend @binding.model_finders
|
94
|
+
@note_one = @binding.create_model Note, :note_one
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should not exist for types that have not been created' do
|
98
|
+
lambda do
|
99
|
+
@context.things(:whatever)
|
100
|
+
end.should raise_error(NoMethodError)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should exist for the base classes of created types' do
|
104
|
+
@binding.create_record State, :state_one
|
105
|
+
@context.places(:state_one).should_not be_nil
|
106
|
+
@context.places(:state_one).should == @context.states(:state_one)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should exist for all ancestors' do
|
110
|
+
@binding.create_record NorthCarolina, :nc
|
111
|
+
@context.states(:nc).should == @context.north_carolinas(:nc)
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should exist for types made with create_model' do
|
115
|
+
@context.notes(:note_one).should == @note_one
|
116
|
+
@context.note_id(:note_one).should == @note_one.id
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should exist for types made with create_record' do
|
120
|
+
id = @binding.create_record Note, :note_two
|
121
|
+
@context.notes(:note_two).id.should == id
|
122
|
+
@context.note_id(:note_two).should == id
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should exist for types registered with name_model' do
|
126
|
+
thing = Thing.create!
|
127
|
+
@binding.name_model(thing, :thingy)
|
128
|
+
@context.things(:thingy).should == thing
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should support multiple names, returning an array' do
|
132
|
+
note_two = @binding.create_model Note, :note_two
|
133
|
+
@context.notes(:note_one, :note_two).should == [@note_one, note_two]
|
134
|
+
@context.note_id(:note_one, :note_two).should == [@note_one.id, note_two.id]
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should support models inside modules' do
|
138
|
+
@binding.create_record Nested::Place, :myplace, :name => 'Home'
|
139
|
+
@context.nested_places(:myplace).name.should == 'Home'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'name_model' do
|
144
|
+
before do
|
145
|
+
@state = State.create!(:name => 'NC')
|
146
|
+
@binding.name_model(@state, :mystate)
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should allow assigning a name to a model for later lookup' do
|
150
|
+
@binding.find_model(State, :mystate).should == @state
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should allow finding STI' do
|
154
|
+
@context = Object.new
|
155
|
+
@context.extend @binding.model_finders
|
156
|
+
@context.places(:mystate).should == @state
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'name_to_sym' do
|
161
|
+
it 'should convert strings to symbols' do
|
162
|
+
@binding.name_to_sym(nil).should == nil
|
163
|
+
@binding.name_to_sym('thing').should == :thing
|
164
|
+
@binding.name_to_sym('Mything').should == :mything
|
165
|
+
@binding.name_to_sym('MyThing').should == :my_thing
|
166
|
+
@binding.name_to_sym('My Thing').should == :my_thing
|
167
|
+
@binding.name_to_sym('"My Thing"').should == :my_thing
|
168
|
+
@binding.name_to_sym('\'My Thing\'').should == :my_thing
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'nested bindings' do
|
173
|
+
before do
|
174
|
+
@binding.create_model Thing, :mything, :name => 'my thing'
|
175
|
+
@nested_binding = Dataset::SessionBinding.new(@binding)
|
176
|
+
end
|
177
|
+
|
178
|
+
it 'should walk up the tree to find models' do
|
179
|
+
@nested_binding.find_model(Thing, :mything).should == @binding.find_model(Thing, :mything)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should raise an error if an object cannot be found for a name' do
|
183
|
+
lambda do
|
184
|
+
@nested_binding.find_model(Thing, :yourthing)
|
185
|
+
end.should raise_error(Dataset::RecordNotFound, "There is no 'Thing' found for the symbolic name ':yourthing'.")
|
186
|
+
|
187
|
+
lambda do
|
188
|
+
@nested_binding.find_id(Thing, :yourthing)
|
189
|
+
end.should raise_error(Dataset::RecordNotFound, "There is no 'Thing' found for the symbolic name ':yourthing'.")
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should have instance loader methods from parent binding' do
|
193
|
+
anything = Object.new
|
194
|
+
anything.extend @nested_binding.model_finders
|
195
|
+
anything.things(:mything).should_not be_nil
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|