be9-dataset 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/CHANGELOG +63 -0
  2. data/LICENSE +19 -0
  3. data/README +111 -0
  4. data/Rakefile +32 -0
  5. data/TODO +15 -0
  6. data/VERSION.yml +5 -0
  7. data/lib/dataset.rb +129 -0
  8. data/lib/dataset/base.rb +157 -0
  9. data/lib/dataset/collection.rb +19 -0
  10. data/lib/dataset/database/base.rb +43 -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/heirarchy.rb +65 -0
  21. data/lib/dataset/record/meta.rb +30 -0
  22. data/lib/dataset/record/model.rb +50 -0
  23. data/lib/dataset/resolver.rb +110 -0
  24. data/lib/dataset/session.rb +51 -0
  25. data/lib/dataset/session_binding.rb +319 -0
  26. data/lib/dataset/version.rb +9 -0
  27. data/plugit/descriptor.rb +25 -0
  28. data/spec/dataset/cucumber_spec.rb +54 -0
  29. data/spec/dataset/database/base_spec.rb +21 -0
  30. data/spec/dataset/record/heirarchy_spec.rb +14 -0
  31. data/spec/dataset/resolver_spec.rb +110 -0
  32. data/spec/dataset/rspec_spec.rb +133 -0
  33. data/spec/dataset/session_binding_spec.rb +203 -0
  34. data/spec/dataset/session_spec.rb +299 -0
  35. data/spec/dataset/test_unit_spec.rb +210 -0
  36. data/spec/fixtures/datasets/constant_not_defined.rb +0 -0
  37. data/spec/fixtures/datasets/ending_with_dataset.rb +2 -0
  38. data/spec/fixtures/datasets/exact_name.rb +2 -0
  39. data/spec/fixtures/datasets/not_a_dataset_base.rb +2 -0
  40. data/spec/fixtures/more_datasets/in_another_directory.rb +2 -0
  41. data/spec/models.rb +18 -0
  42. data/spec/schema.rb +26 -0
  43. data/spec/spec_helper.rb +47 -0
  44. data/spec/stubs/mini_rails.rb +18 -0
  45. data/spec/stubs/test_help.rb +1 -0
  46. data/tasks/dataset.rake +19 -0
  47. metadata +163 -0
@@ -0,0 +1,299 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ TestCaseRoot = Class.new(Test::Unit::TestCase)
4
+ TestCaseChild = Class.new(TestCaseRoot)
5
+ TestCaseSibling = Class.new(TestCaseRoot)
6
+ TestCaseGrandchild = Class.new(TestCaseChild)
7
+
8
+ DatasetOne = Class.new(Dataset::Base)
9
+ DatasetTwo = Class.new(Dataset::Base)
10
+
11
+ describe Dataset::Session do
12
+ before do
13
+ @database = Dataset::Database::Sqlite3.new({:database => SQLITE_DATABASE}, "#{SPEC_ROOT}/tmp")
14
+ @session = Dataset::Session.new(@database)
15
+ end
16
+
17
+ describe 'dataset associations' do
18
+ it 'should allow the addition of datasets for a test' do
19
+ @session.add_dataset TestCaseRoot, DatasetOne
20
+ @session.datasets_for(TestCaseRoot).should == [DatasetOne]
21
+
22
+ @session.add_dataset TestCaseRoot, DatasetTwo
23
+ @session.datasets_for(TestCaseRoot).should == [DatasetOne, DatasetTwo]
24
+
25
+ @session.add_dataset TestCaseRoot, DatasetOne
26
+ @session.datasets_for(TestCaseRoot).should == [DatasetOne, DatasetTwo]
27
+ end
28
+
29
+ it 'should combine datasets from test superclasses into subclasses' do
30
+ @session.add_dataset TestCaseRoot, DatasetOne
31
+ @session.add_dataset TestCaseChild, DatasetTwo
32
+ @session.add_dataset TestCaseChild, DatasetOne
33
+ @session.datasets_for(TestCaseChild).should == [DatasetOne, DatasetTwo]
34
+ @session.datasets_for(TestCaseGrandchild).should == [DatasetOne, DatasetTwo]
35
+ end
36
+
37
+ it 'should include those that a dataset declares it uses' do
38
+ dataset_one = Class.new(Dataset::Base) do
39
+ uses DatasetTwo
40
+ end
41
+ dataset_two = Class.new(Dataset::Base) do
42
+ uses dataset_one, DatasetOne
43
+ end
44
+ @session.add_dataset TestCaseRoot, dataset_two
45
+ @session.add_dataset TestCaseChild, DatasetTwo
46
+ @session.datasets_for(TestCaseChild).should == [DatasetTwo, dataset_one, DatasetOne, dataset_two]
47
+ @session.datasets_for(TestCaseGrandchild).should == [DatasetTwo, dataset_one, DatasetOne, dataset_two]
48
+ end
49
+
50
+ it 'should accept a dataset name' do
51
+ @session.add_dataset TestCaseRoot, :dataset_one
52
+ @session.datasets_for(TestCaseRoot).should == [DatasetOne]
53
+
54
+ dataset = Class.new(Dataset::Base) do
55
+ uses :dataset_two, :dataset_one
56
+ end
57
+ @session.add_dataset TestCaseChild, dataset
58
+ @session.datasets_for(TestCaseChild).should == [DatasetOne, DatasetTwo, dataset]
59
+ end
60
+ end
61
+
62
+ describe 'dataset loading' do
63
+ it 'should clear the database on first load' do
64
+ @database.should_receive(:clear).once()
65
+ dataset_one = Class.new(Dataset::Base)
66
+ dataset_two = Class.new(Dataset::Base)
67
+ @session.add_dataset TestCaseRoot, dataset_one
68
+ @session.add_dataset TestCaseChild, dataset_one
69
+ @session.load_datasets_for(TestCaseRoot)
70
+ @session.load_datasets_for(TestCaseChild)
71
+ end
72
+
73
+ it 'should clear the database on loads where there is no subset' do
74
+ @database.should_receive(:clear).twice()
75
+ dataset_one = Class.new(Dataset::Base)
76
+ dataset_two = Class.new(Dataset::Base)
77
+ @session.add_dataset TestCaseChild, dataset_one
78
+ @session.add_dataset TestCaseSibling, dataset_two
79
+ @session.load_datasets_for(TestCaseChild)
80
+ @session.load_datasets_for(TestCaseSibling)
81
+ end
82
+
83
+ it 'should not capture the dataset if it is the same as the last loaded' do
84
+ @database.should_not_receive(:capture)
85
+ dataset_one = Class.new(Dataset::Base)
86
+ @session.add_dataset TestCaseRoot, dataset_one
87
+ @session.load_datasets_for(TestCaseRoot)
88
+ @session.load_datasets_for(TestCaseChild)
89
+ @session.load_datasets_for(TestCaseSibling)
90
+ end
91
+
92
+ it 'should happen in the order declared' do
93
+ load_order = []
94
+
95
+ dataset_one = Class.new(Dataset::Base) {
96
+ define_method :load do
97
+ load_order << self.class
98
+ end
99
+ }
100
+ dataset_two = Class.new(Dataset::Base) {
101
+ define_method :load do
102
+ load_order << self.class
103
+ end
104
+ }
105
+
106
+ @session.add_dataset TestCaseRoot, dataset_two
107
+ @session.add_dataset TestCaseRoot, dataset_one
108
+ @session.load_datasets_for TestCaseRoot
109
+ load_order.should == [dataset_two, dataset_one]
110
+ end
111
+
112
+ it 'should install dataset helpers into defining dataset, and not cross into other datasets' do
113
+ dataset_instances = []
114
+ dataset_one = Class.new(Dataset::Base) {
115
+ helpers do
116
+ def helper_one; end
117
+ end
118
+ define_method :load do
119
+ dataset_instances << self
120
+ end
121
+ }
122
+ dataset_two = Class.new(Dataset::Base) {
123
+ helpers do
124
+ def helper_two; end
125
+ end
126
+ define_method :load do
127
+ dataset_instances << self
128
+ end
129
+ }
130
+ @session.add_dataset TestCaseRoot, dataset_one
131
+ @session.add_dataset TestCaseRoot, dataset_two
132
+ @session.load_datasets_for TestCaseRoot
133
+ dataset_instances.first.should respond_to(:helper_one)
134
+ dataset_instances.first.should_not respond_to(:helper_two)
135
+ dataset_instances.last.should_not respond_to(:helper_one)
136
+ dataset_instances.last.should respond_to(:helper_two)
137
+
138
+ dataset_one.instance_methods.should include('helper_one')
139
+ dataset_one.instance_methods.should_not include('helper_two')
140
+ dataset_two.instance_methods.should_not include('helper_one')
141
+ dataset_two.instance_methods.should include('helper_two')
142
+ end
143
+
144
+ it 'should install dataset helpers into datasets that are using another' do
145
+ dataset_instances = []
146
+ dataset_one = Class.new(Dataset::Base) {
147
+ helpers do
148
+ def helper_one; end
149
+ end
150
+ define_method :load do
151
+ dataset_instances << self
152
+ end
153
+ }
154
+ dataset_two = Class.new(Dataset::Base) {
155
+ uses dataset_one
156
+ helpers do
157
+ def helper_two; end
158
+ end
159
+ define_method :load do
160
+ dataset_instances << self
161
+ end
162
+ }
163
+ @session.add_dataset TestCaseRoot, dataset_one
164
+ @session.add_dataset TestCaseRoot, dataset_two
165
+ @session.load_datasets_for TestCaseRoot
166
+ dataset_instances.first.should respond_to(:helper_one)
167
+ dataset_instances.first.should_not respond_to(:helper_two)
168
+ dataset_instances.last.should respond_to(:helper_one)
169
+ dataset_instances.last.should respond_to(:helper_two)
170
+
171
+ dataset_one.instance_methods.should include('helper_one')
172
+ dataset_one.instance_methods.should_not include('helper_two')
173
+ dataset_two.instance_methods.should_not include('helper_one')
174
+ dataset_two.instance_methods.should include('helper_two')
175
+ end
176
+
177
+ it 'should happen only once per test in a hierarchy' do
178
+ load_count = 0
179
+
180
+ dataset = Class.new(Dataset::Base) {
181
+ define_method :load do
182
+ load_count += 1
183
+ end
184
+ }
185
+
186
+ @session.add_dataset TestCaseRoot, dataset
187
+ @session.load_datasets_for TestCaseRoot
188
+ load_count.should == 1
189
+
190
+ @session.load_datasets_for TestCaseRoot
191
+ load_count.should == 1
192
+
193
+ @session.load_datasets_for TestCaseChild
194
+ load_count.should == 1
195
+ end
196
+
197
+ it 'should capture the existing data before loading a superset, restoring the subset before a peer runs' do
198
+ dataset_one_load_count = 0
199
+ dataset_one = Class.new(Dataset::Base) do
200
+ define_method :load do
201
+ dataset_one_load_count += 1
202
+ Thing.create!
203
+ end
204
+ end
205
+
206
+ dataset_two_load_count = 0
207
+ dataset_two = Class.new(Dataset::Base) do
208
+ define_method :load do
209
+ dataset_two_load_count += 1
210
+ Place.create!
211
+ end
212
+ end
213
+
214
+ @session.add_dataset TestCaseRoot, dataset_one
215
+ @session.add_dataset TestCaseChild, dataset_two
216
+
217
+ @session.load_datasets_for TestCaseRoot
218
+ dataset_one_load_count.should == 1
219
+ dataset_two_load_count.should == 0
220
+ Thing.count.should == 1
221
+ Place.count.should == 0
222
+
223
+ @session.load_datasets_for TestCaseChild
224
+ dataset_one_load_count.should == 1
225
+ dataset_two_load_count.should == 1
226
+ Thing.count.should == 1
227
+ Place.count.should == 1
228
+
229
+ @session.load_datasets_for TestCaseSibling
230
+ dataset_one_load_count.should == 1
231
+ dataset_two_load_count.should == 1
232
+ Thing.count.should == 1
233
+ Place.count.should == 0
234
+ end
235
+
236
+ it 'should install the record methods into the datasets' do
237
+ instance_of_dataset_one = nil
238
+ dataset_one = Class.new(Dataset::Base) do
239
+ define_method :load do
240
+ instance_of_dataset_one = self
241
+ end
242
+ end
243
+
244
+ @session.add_dataset TestCaseRoot, dataset_one
245
+ @session.load_datasets_for TestCaseRoot
246
+ instance_of_dataset_one.should_not be_nil
247
+ instance_of_dataset_one.should respond_to(:create_record)
248
+ instance_of_dataset_one.should respond_to(:create_model)
249
+ instance_of_dataset_one.should respond_to(:name_model)
250
+ instance_of_dataset_one.should respond_to(:find_model)
251
+ instance_of_dataset_one.should respond_to(:find_id)
252
+ end
253
+
254
+ it 'should install the instance loader methods into the dataset instance' do
255
+ instance_of_dataset_one = nil
256
+ dataset_one = Class.new(Dataset::Base) do
257
+ define_method :load do
258
+ create_record(Thing)
259
+ instance_of_dataset_one = self
260
+ end
261
+ end
262
+
263
+ @session.add_dataset TestCaseRoot, dataset_one
264
+ @session.load_datasets_for TestCaseRoot
265
+ instance_of_dataset_one.should respond_to(:things)
266
+ end
267
+
268
+ it 'should copy instance variables assigned in dataset blocks to binding' do
269
+ @session.add_dataset(TestCaseRoot, Class.new(Dataset::Block) {
270
+ define_method :doload do
271
+ @myvar = 'Hello'
272
+ end
273
+ })
274
+ load = @session.load_datasets_for(TestCaseRoot)
275
+ load.dataset_binding.block_variables['@myvar'].should == 'Hello'
276
+ end
277
+ end
278
+
279
+ describe 'bindings' do
280
+ it 'should be created for each dataset load, wrapping the outer binding' do
281
+ binding_one = Dataset::SessionBinding.new(@database)
282
+ binding_two = Dataset::SessionBinding.new(binding_one)
283
+ binding_three = Dataset::SessionBinding.new(binding_one)
284
+
285
+ Dataset::SessionBinding.should_receive(:new).with(@database).and_return(binding_one)
286
+ Dataset::SessionBinding.should_receive(:new).with(binding_one).twice().and_return(binding_two)
287
+
288
+ dataset_one = Class.new(Dataset::Base) { define_method :load do; end }
289
+ dataset_two = Class.new(Dataset::Base) { define_method :load do; end }
290
+
291
+ @session.add_dataset TestCaseRoot, dataset_one
292
+ @session.add_dataset TestCaseChild, dataset_two
293
+
294
+ @session.load_datasets_for TestCaseRoot
295
+ @session.load_datasets_for TestCaseChild
296
+ @session.load_datasets_for TestCaseSibling
297
+ end
298
+ end
299
+ end
@@ -0,0 +1,210 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ require 'test/unit/testresult'
4
+ class Test::Unit::TestCase
5
+ include Dataset
6
+ end
7
+
8
+ describe Test::Unit::TestCase do
9
+ it 'should have a dataset method' do
10
+ testcase = Class.new(Test::Unit::TestCase)
11
+ testcase.should respond_to(:dataset)
12
+ end
13
+
14
+ it 'should accept multiple datasets' do
15
+ load_count = 0
16
+ dataset_one = Class.new(Dataset::Base) do
17
+ define_method(:load) { load_count += 1 }
18
+ end
19
+ dataset_two = Class.new(Dataset::Base) do
20
+ define_method(:load) { load_count += 1 }
21
+ end
22
+ testcase = Class.new(Test::Unit::TestCase) do
23
+ dataset dataset_one, dataset_two
24
+ end
25
+ run_testcase(testcase)
26
+ load_count.should be(2)
27
+ end
28
+
29
+ it 'should provide one dataset session for tests' do
30
+ sessions = []
31
+ testcase = Class.new(Test::Unit::TestCase) do
32
+ dataset Class.new(Dataset::Base)
33
+
34
+ define_method(:test_one) do
35
+ sessions << dataset_session
36
+ end
37
+ define_method(:test_two) do
38
+ sessions << dataset_session
39
+ end
40
+ end
41
+ run_testcase(testcase)
42
+ sessions.size.should be(2)
43
+ sessions.uniq.size.should be(1)
44
+ end
45
+
46
+ it 'should load datasets within class hiearchy' do
47
+ dataset_one = Class.new(Dataset::Base) do
48
+ define_method(:load) do
49
+ Thing.create!
50
+ end
51
+ end
52
+ dataset_two = Class.new(Dataset::Base) do
53
+ define_method(:load) do
54
+ Place.create!
55
+ end
56
+ end
57
+
58
+ testcase = Class.new(Test::Unit::TestCase) do
59
+ dataset(dataset_one)
60
+ def test_one; end
61
+ end
62
+ testcase_child = Class.new(testcase) do
63
+ dataset(dataset_two)
64
+ def test_two; end
65
+ end
66
+
67
+ run_testcase(testcase)
68
+ Thing.count.should be(1)
69
+ Place.count.should be(0)
70
+
71
+ run_testcase(testcase_child)
72
+ Thing.count.should be(1)
73
+ Place.count.should be(1)
74
+ end
75
+
76
+ it 'should forward blocks passed in to the dataset method' do
77
+ load_count = 0
78
+ testcase = Class.new(Test::Unit::TestCase) do
79
+ dataset_class = Class.new(Dataset::Base)
80
+ dataset dataset_class do
81
+ load_count += 1
82
+ end
83
+ end
84
+
85
+ run_testcase(testcase)
86
+ load_count.should == 1
87
+ end
88
+
89
+ it 'should forward blocks passed in to the dataset method that do not use a dataset class' do
90
+ load_count = 0
91
+ testcase = Class.new(Test::Unit::TestCase) do
92
+ dataset do
93
+ load_count += 1
94
+ end
95
+ end
96
+
97
+ run_testcase(testcase)
98
+ load_count.should == 1
99
+ end
100
+
101
+ it 'should copy instance variables from block to tests' do
102
+ value_in_test = nil
103
+ testcase = Class.new(Test::Unit::TestCase) do
104
+ dataset do
105
+ @myvar = 'Hello'
106
+ end
107
+ define_method :test_something do
108
+ value_in_test = @myvar
109
+ end
110
+ end
111
+
112
+ run_testcase(testcase)
113
+ value_in_test.should == 'Hello'
114
+ end
115
+
116
+ it 'should copy instance variables from block to subclass blocks' do
117
+ value_in_subclass_block = nil
118
+ testcase = Class.new(Test::Unit::TestCase) do
119
+ dataset do
120
+ @myvar = 'Hello'
121
+ end
122
+ end
123
+ subclass = Class.new(testcase) do
124
+ dataset do
125
+ value_in_subclass_block = @myvar
126
+ end
127
+ end
128
+
129
+ run_testcase(subclass)
130
+ value_in_subclass_block.should == 'Hello'
131
+ end
132
+
133
+ it 'should load the dataset when the suite is run' do
134
+ load_count = 0
135
+ dataset = Class.new(Dataset::Base) do
136
+ define_method(:load) do
137
+ load_count += 1
138
+ end
139
+ end
140
+
141
+ testcase = Class.new(Test::Unit::TestCase) do
142
+ self.dataset(dataset)
143
+ def test_one; end
144
+ def test_two; end
145
+ end
146
+
147
+ run_testcase(testcase)
148
+ load_count.should be(1)
149
+ end
150
+
151
+ it 'should expose data reading methods from dataset binding to the test methods through the test instances' do
152
+ created_model, found_model = nil
153
+ dataset = Class.new(Dataset::Base) do
154
+ define_method(:load) do
155
+ created_model = create_model(Thing, :mything)
156
+ end
157
+ end
158
+
159
+ testcase = Class.new(Test::Unit::TestCase) do
160
+ self.dataset(dataset)
161
+ define_method :test_model_finders do
162
+ found_model = things(:mything)
163
+ end
164
+ end
165
+
166
+ run_testcase(testcase)
167
+ testcase.should_not respond_to(:things)
168
+ found_model.should_not be_nil
169
+ found_model.should == created_model
170
+ end
171
+
172
+ it 'should expose dataset helper methods to the test methods through the test instances' do
173
+ dataset_one = Class.new(Dataset::Base) do
174
+ helpers do
175
+ def helper_one; end
176
+ end
177
+ def load; end
178
+ end
179
+ dataset_two = Class.new(Dataset::Base) do
180
+ uses dataset_one
181
+ helpers do
182
+ def helper_two; end
183
+ end
184
+ def load; end
185
+ end
186
+
187
+ test_instance = nil
188
+ testcase = Class.new(Test::Unit::TestCase) do
189
+ self.dataset(dataset_two)
190
+ define_method :test_model_finders do
191
+ test_instance = self
192
+ end
193
+ end
194
+
195
+ run_testcase(testcase)
196
+
197
+ testcase.should_not respond_to(:helper_one)
198
+ testcase.should_not respond_to(:helper_two)
199
+ test_instance.should respond_to(:helper_one)
200
+ test_instance.should respond_to(:helper_two)
201
+ end
202
+
203
+ def run_testcase(testcase)
204
+ result = Test::Unit::TestResult.new
205
+ testcase.module_eval { def test_dont_complain; end }
206
+ testcase.suite.run(result) {}
207
+ result.failure_count.should be(0)
208
+ result.error_count.should be(0)
209
+ end
210
+ end