dataset 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/CHANGELOG +59 -0
  2. data/LICENSE +19 -0
  3. data/README +111 -0
  4. data/Rakefile +31 -0
  5. data/TODO +15 -0
  6. data/VERSION.yml +4 -0
  7. data/lib/dataset.rb +128 -0
  8. data/lib/dataset/base.rb +157 -0
  9. data/lib/dataset/collection.rb +19 -0
  10. data/lib/dataset/database/base.rb +30 -0
  11. data/lib/dataset/database/mysql.rb +34 -0
  12. data/lib/dataset/database/postgresql.rb +34 -0
  13. data/lib/dataset/database/sqlite3.rb +32 -0
  14. data/lib/dataset/extensions/cucumber.rb +20 -0
  15. data/lib/dataset/extensions/rspec.rb +21 -0
  16. data/lib/dataset/extensions/test_unit.rb +60 -0
  17. data/lib/dataset/instance_methods.rb +10 -0
  18. data/lib/dataset/load.rb +47 -0
  19. data/lib/dataset/record/fixture.rb +73 -0
  20. data/lib/dataset/record/meta.rb +66 -0
  21. data/lib/dataset/record/model.rb +50 -0
  22. data/lib/dataset/resolver.rb +110 -0
  23. data/lib/dataset/session.rb +51 -0
  24. data/lib/dataset/session_binding.rb +317 -0
  25. data/lib/dataset/version.rb +9 -0
  26. data/plugit/descriptor.rb +25 -0
  27. data/spec/dataset/cucumber_spec.rb +54 -0
  28. data/spec/dataset/database/base_spec.rb +21 -0
  29. data/spec/dataset/record/meta_spec.rb +14 -0
  30. data/spec/dataset/resolver_spec.rb +110 -0
  31. data/spec/dataset/rspec_spec.rb +133 -0
  32. data/spec/dataset/session_binding_spec.rb +198 -0
  33. data/spec/dataset/session_spec.rb +299 -0
  34. data/spec/dataset/test_unit_spec.rb +210 -0
  35. data/spec/fixtures/datasets/constant_not_defined.rb +0 -0
  36. data/spec/fixtures/datasets/ending_with_dataset.rb +2 -0
  37. data/spec/fixtures/datasets/exact_name.rb +2 -0
  38. data/spec/fixtures/datasets/not_a_dataset_base.rb +2 -0
  39. data/spec/fixtures/more_datasets/in_another_directory.rb +2 -0
  40. data/spec/models.rb +18 -0
  41. data/spec/schema.rb +26 -0
  42. data/spec/spec_helper.rb +47 -0
  43. data/spec/stubs/mini_rails.rb +18 -0
  44. data/spec/stubs/test_help.rb +1 -0
  45. data/tasks/dataset.rake +19 -0
  46. metadata +120 -0
@@ -0,0 +1,9 @@
1
+ module Dataset
2
+ module VERSION #:nodoc:
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ TINY = 0
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -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