dataset 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/CHANGELOG
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
*1.3.0 [Rails 2.3.2] (??)
|
2
|
+
|
3
|
+
* Supporting Rails 2.3.2 [mhawkins, underlog]
|
4
|
+
* Added tasks to load path so folks can require 'dataset.rake' [aiwilliams]
|
5
|
+
* Updated gemspec to include dependencies [aiwilliams]
|
6
|
+
|
7
|
+
*1.2.0 [Cucumber] (April 8, 2009)
|
8
|
+
|
9
|
+
* Support for cucumber [jgarber, seancribbs]
|
10
|
+
|
11
|
+
*1.1.0 [STI, belongs_to] (February 14, 2009)
|
12
|
+
|
13
|
+
* STI is better supported for inserting, naming and finding records [aiwilliams]
|
14
|
+
|
15
|
+
class Place < ActiveRecord::Base; end
|
16
|
+
class State < Place; end
|
17
|
+
class NorthCarolina < State; end
|
18
|
+
|
19
|
+
create_record(NorthCarolina, :state) # no need to define the 'type' column value
|
20
|
+
states(:state) == places(:state) == north_carolinas(:state) # read with the class names pluralized
|
21
|
+
|
22
|
+
* Moved to jeweler for much cleaner, github embracing gem building [aiwilliams]
|
23
|
+
* Support for simple belongs to associations [aiwilliams]
|
24
|
+
|
25
|
+
class Person < ActiveRecord::Base; end
|
26
|
+
class Note < ActiveRecord::Base
|
27
|
+
belongs_to :person
|
28
|
+
end
|
29
|
+
|
30
|
+
person_id = create_record Person, :myguy
|
31
|
+
create_record Note, :person => :myguy
|
32
|
+
Note.last.person_id == person_id
|
33
|
+
|
34
|
+
* Models inside modules are supported a little more conveniently [aiwilliams]
|
35
|
+
|
36
|
+
module MList
|
37
|
+
class Message < ActiveRecord::Base
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# We'll get rid of the underscore in 'm_list_messages'
|
42
|
+
create_record MList::Message, :test
|
43
|
+
mlist_messages(:test)
|
44
|
+
|
45
|
+
* Helper method for converting strings to useful symbols for finding records [siannopollo]
|
46
|
+
|
47
|
+
This is useful if you write creator methods of your own.
|
48
|
+
|
49
|
+
def create_person(attributes)
|
50
|
+
create_record Person, name_to_sym(attributes[:name]), attributes
|
51
|
+
end
|
52
|
+
|
53
|
+
create_person(:name => 'Little John')
|
54
|
+
people(:little_john)
|
55
|
+
|
56
|
+
|
57
|
+
*1.0.0 [Scenarios Replacement] (December 15, 2008)
|
58
|
+
|
59
|
+
* Drop-in replacement for Scenarios plugin of old [aiwilliams]
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2008-2009, Adam Williams
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
= Dataset
|
2
|
+
|
3
|
+
Dataset provides a simple API for creating and finding sets of data in your database. Check out Dataset::RecordMethods and Dataset::ModelFinders.
|
4
|
+
|
5
|
+
Dataset loads data intelligently if you use 'nested contexts' in your tests (RSpec, anything that uses Test::Unit::TestCase subclassing for creating nested contexts):
|
6
|
+
|
7
|
+
describe Something do
|
8
|
+
dataset :a => Dataset :a is loaded (at the right time)
|
9
|
+
|
10
|
+
it 'should whatever'
|
11
|
+
end
|
12
|
+
|
13
|
+
describe More do
|
14
|
+
dataset :b => Dataset :b is loaded. :a data is still there
|
15
|
+
|
16
|
+
it 'should'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Another do => Database is restored to :a, without re-running :a logic
|
21
|
+
it 'should'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
The goal is to see a marked improvement in overall test run speed, basing this on the assumption that it is faster to have the OS copy a file or mySQL dump and load. Of course, we may find this to be a false assumption, but there were plenty of bugs in the former 'Scenarios' - addressing that afforded the opportunity to test the assumption.
|
27
|
+
|
28
|
+
|
29
|
+
Dataset does not prevent you from using other libraries like Machinist or factory_girl. If you were to used either of those, you could have a dataset like this:
|
30
|
+
|
31
|
+
require 'faker'
|
32
|
+
|
33
|
+
class OrganizationsDataset < Dataset::Base
|
34
|
+
Sham.name { Faker::Name.name }
|
35
|
+
|
36
|
+
Organization.blueprint do
|
37
|
+
name { Sham.name }
|
38
|
+
end
|
39
|
+
|
40
|
+
def load
|
41
|
+
name_model Organization.make, :org_one
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
The benefit is that you can reuse interesting sets of data, without sacrificing the utility of those other libraries.
|
46
|
+
|
47
|
+
describe Organization, 'stuff' do
|
48
|
+
dataset :organizations
|
49
|
+
end
|
50
|
+
|
51
|
+
describe Organization, 'other stuff' do
|
52
|
+
dataset :organizations
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
Get things installed, then read more in the Dataset documentation at http://aiwilliams.github.com/dataset
|
57
|
+
|
58
|
+
|
59
|
+
== Installation
|
60
|
+
|
61
|
+
Install the plugin:
|
62
|
+
|
63
|
+
./script/plugin install git://github.com/aiwilliams/dataset.git
|
64
|
+
|
65
|
+
In your test_helper.rb/spec_helper.rb:
|
66
|
+
|
67
|
+
require 'dataset'
|
68
|
+
class Test::Unit::TestCase
|
69
|
+
include Dataset
|
70
|
+
datasets_directory "#{RAILS_ROOT}/spec/datasets"
|
71
|
+
end
|
72
|
+
|
73
|
+
If you don't use rspec_on_rails, or you have specs that aren't of the RailsExampleGroup type, you should do this in spec_helper.rb:
|
74
|
+
|
75
|
+
require 'dataset'
|
76
|
+
class Spec::Example::ExampleGroup
|
77
|
+
include Dataset
|
78
|
+
datasets_directory "#{RAILS_ROOT}/spec/datasets"
|
79
|
+
end
|
80
|
+
|
81
|
+
If you were a user of the Scenarios plugin, and want to do as little as possible to get going (assumes you are using rspec_on_rails):
|
82
|
+
|
83
|
+
require 'dataset'
|
84
|
+
Scenario = Scenarios = Dataset
|
85
|
+
class Test::Unit::TestCase
|
86
|
+
include Dataset
|
87
|
+
class << self
|
88
|
+
alias_method :scenario, :dataset
|
89
|
+
end
|
90
|
+
end
|
91
|
+
class ScenariosResolver < Dataset::DirectoryResolver
|
92
|
+
def suffix
|
93
|
+
@suffix ||= 'Scenario'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
Dataset::Resolver.default = ScenariosResolver.new("#{RAILS_ROOT}/spec/scenarios")
|
97
|
+
|
98
|
+
|
99
|
+
== Credits
|
100
|
+
|
101
|
+
Written by [Adam Williams](http://github.com/aiwilliams).
|
102
|
+
|
103
|
+
Contributors:
|
104
|
+
|
105
|
+
- [Saturn Flyer](http://www.saturnflyer.com) [github](http://github.com/saturnflyer)
|
106
|
+
- [Steve Iannopollo](http://github.com/siannopollo)
|
107
|
+
- [John Long](http://github.com/jlong)
|
108
|
+
|
109
|
+
---
|
110
|
+
|
111
|
+
Dataset is released under the MIT-License and is Copyright (c)2008 Adam Williams.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
|
2
|
+
|
3
|
+
require File.join(File.dirname(__FILE__), 'plugit/descriptor')
|
4
|
+
require 'rubygems'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
desc "Run all specs"
|
10
|
+
Spec::Rake::SpecTask.new do |t|
|
11
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
12
|
+
t.spec_opts = ['--options', 'spec/spec.opts']
|
13
|
+
end
|
14
|
+
|
15
|
+
begin
|
16
|
+
require 'jeweler'
|
17
|
+
Jeweler::Tasks.new do |s|
|
18
|
+
s.name = 'dataset'
|
19
|
+
s.summary = 'A simple API for creating and finding sets of data in your database, built on ActiveRecord.'
|
20
|
+
s.email = 'adam@thewilliams.ws'
|
21
|
+
s.files = FileList["[A-Z]*", "{lib,tasks}/**/*", "plugit/descriptor.rb"].exclude("tmp")
|
22
|
+
s.require_paths = ["lib", "tasks"]
|
23
|
+
s.add_dependency('activesupport', '>= 2.3.0')
|
24
|
+
s.add_dependency('activerecord', '>= 2.3.0')
|
25
|
+
s.homepage = "http://github.com/aiwilliams/dataset"
|
26
|
+
s.description = s.summary
|
27
|
+
s.authors = ['Adam Williams']
|
28
|
+
end
|
29
|
+
rescue LoadError
|
30
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
31
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
take any instance variables already in context and make them available to dataset blocks - this is for nested describes
|
2
|
+
I'm not sure about this one. It can be very frustrating to lose context of when the state of an iv is modified.
|
3
|
+
|
4
|
+
add ability to clear the database (some tests wanted to guarantee a clear db)
|
5
|
+
This is acheived with "dataset {}"
|
6
|
+
|
7
|
+
clear database completely at beginning of session, only tables where data was created within a session??
|
8
|
+
|
9
|
+
clear all dumps on new run of tests
|
10
|
+
be sure we are capturing a dataset if it has already be captured before during a run
|
11
|
+
describe what happens when someone has a fixtures file - they get loaded after our datasets, thereby causing all the data in the table of the fixture file (like things.yml) to be deleted - the fixtures are then loaded
|
12
|
+
look into truncating database instead individual table deletes
|
13
|
+
allow configuration of dataset
|
14
|
+
* permatable / global scope
|
15
|
+
re-evaluation location of some tests that depend on TestCase in non-test/unit tests
|
data/VERSION.yml
ADDED
data/lib/dataset.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require 'activesupport'
|
2
|
+
require 'activerecord'
|
3
|
+
|
4
|
+
require 'dataset/version'
|
5
|
+
require 'dataset/instance_methods'
|
6
|
+
require 'dataset/base'
|
7
|
+
require 'dataset/database/base'
|
8
|
+
require 'dataset/database/mysql'
|
9
|
+
require 'dataset/database/sqlite3'
|
10
|
+
require 'dataset/database/postgresql'
|
11
|
+
require 'dataset/collection'
|
12
|
+
require 'dataset/load'
|
13
|
+
require 'dataset/resolver'
|
14
|
+
require 'dataset/session'
|
15
|
+
require 'dataset/session_binding'
|
16
|
+
require 'dataset/record/meta'
|
17
|
+
require 'dataset/record/fixture'
|
18
|
+
require 'dataset/record/model'
|
19
|
+
|
20
|
+
# == Quick Start
|
21
|
+
#
|
22
|
+
# Write a test. If you want some data in your database, create a dataset.
|
23
|
+
# Start simple.
|
24
|
+
#
|
25
|
+
# describe States do
|
26
|
+
# dataset do
|
27
|
+
# [%w(Colorado CO), %w(North\ Carolina NC), %w(South\ Carolina SC)].each do |name,abbrev|
|
28
|
+
# create_record :state, abbrev.downcase, :name => name, :abbrev => abbrev
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# it 'should have an abbreviated name'
|
33
|
+
# states(:nc).abbrev.should be('NC')
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# it 'should have a name'
|
37
|
+
# states(:nc).name.should be('North Carolin')
|
38
|
+
# end
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# Notice that you won't be using _find_id_ or _find_model_ in your tests. You
|
42
|
+
# use methods like _states_ and _state_id_, as in the example above.
|
43
|
+
#
|
44
|
+
# When you find that you're seeing patterns in the data you are creating, pull it into a class.
|
45
|
+
#
|
46
|
+
# spec/datasets/states.rb
|
47
|
+
# class StatesDataset < Dataset::Base
|
48
|
+
# def load
|
49
|
+
# # create useful data
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# spec/models/state.rb
|
54
|
+
# describe State do
|
55
|
+
# dataset :states
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# == Installation
|
59
|
+
#
|
60
|
+
# Dataset is installed into your testing environment by requiring the library,
|
61
|
+
# then including it into the class that will be the context of your test
|
62
|
+
# methods.
|
63
|
+
#
|
64
|
+
# require 'dataset'
|
65
|
+
# class Test::Unit::TestCase
|
66
|
+
# include Dataset
|
67
|
+
# datasets_directory "#{RAILS_ROOT}/test/datasets"
|
68
|
+
# end
|
69
|
+
#
|
70
|
+
# Note that should you desire your Dataset::Base subclasses be
|
71
|
+
# auto-discovered, you can set the _datasets_directory_.
|
72
|
+
#
|
73
|
+
module Dataset
|
74
|
+
def self.included(test_context) # :nodoc:
|
75
|
+
if test_context.name =~ /World\Z/
|
76
|
+
require 'dataset/extensions/cucumber'
|
77
|
+
elsif test_context.name =~ /TestCase\Z/
|
78
|
+
require 'dataset/extensions/test_unit'
|
79
|
+
elsif test_context.name =~ /ExampleGroup\Z/
|
80
|
+
require 'dataset/extensions/rspec'
|
81
|
+
else
|
82
|
+
raise "I don't understand your test framework"
|
83
|
+
end
|
84
|
+
|
85
|
+
test_context.extend ContextClassMethods
|
86
|
+
end
|
87
|
+
|
88
|
+
# Methods that are added to the class that Dataset is included in (the test
|
89
|
+
# context class).
|
90
|
+
#
|
91
|
+
module ContextClassMethods
|
92
|
+
def self.extended(context_class) # :nodoc:
|
93
|
+
context_class.module_eval do
|
94
|
+
include InstanceMethods
|
95
|
+
superclass_delegating_accessor :dataset_session
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
mattr_accessor :datasets_database_dump_path
|
100
|
+
self.datasets_database_dump_path = File.expand_path(RAILS_ROOT + '/tmp/dataset') if defined?(RAILS_ROOT)
|
101
|
+
|
102
|
+
# Replaces the default Dataset::Resolver with one that will look for
|
103
|
+
# dataset class definitions in the specified directory. Captures of the
|
104
|
+
# database will be stored in a subdirectory 'tmp' (see
|
105
|
+
# Dataset::Database::Base).
|
106
|
+
def datasets_directory(path)
|
107
|
+
Dataset::Resolver.default = Dataset::DirectoryResolver.new(path)
|
108
|
+
Dataset::ContextClassMethods.datasets_database_dump_path = File.join(path, '/tmp/dataset')
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_dataset(*datasets, &block) # :nodoc:
|
112
|
+
dataset_session = dataset_session_in_hierarchy
|
113
|
+
datasets.each { |dataset| dataset_session.add_dataset(self, dataset) }
|
114
|
+
dataset_session.add_dataset(self, Class.new(Dataset::Block) {
|
115
|
+
define_method :doload, block
|
116
|
+
}) unless block.nil?
|
117
|
+
end
|
118
|
+
|
119
|
+
def dataset_session_in_hierarchy # :nodoc:
|
120
|
+
self.dataset_session ||= begin
|
121
|
+
database_spec = ActiveRecord::Base.configurations['test'].with_indifferent_access
|
122
|
+
database_class = Dataset::Database.const_get(database_spec[:adapter].classify)
|
123
|
+
database = database_class.new(database_spec, Dataset::ContextClassMethods.datasets_database_dump_path)
|
124
|
+
Dataset::Session.new(database)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
data/lib/dataset/base.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
module Dataset
|
2
|
+
|
3
|
+
# The superclass of your Dataset classes.
|
4
|
+
#
|
5
|
+
# It is recommended that you create a dataset using the Dataset::Block
|
6
|
+
# method first, then grow into using classes as you recognize patterns in
|
7
|
+
# your test data creation. This will help you to keep simple things simple.
|
8
|
+
#
|
9
|
+
class Base
|
10
|
+
class << self
|
11
|
+
# Allows a subclass to define helper methods that should be made
|
12
|
+
# available to instances of this dataset, to datasets that use this
|
13
|
+
# dataset, and to tests that use this dataset.
|
14
|
+
#
|
15
|
+
# This feature is great for providing any kind of method that would help
|
16
|
+
# test the code around the data your dataset creates. Be careful,
|
17
|
+
# though, to keep from adding business logic to these methods! That
|
18
|
+
# belongs in your production code.
|
19
|
+
#
|
20
|
+
def helpers(&method_definitions)
|
21
|
+
@helper_methods ||= begin
|
22
|
+
mod = Module.new
|
23
|
+
include mod
|
24
|
+
mod
|
25
|
+
end
|
26
|
+
@helper_methods.module_eval &method_definitions
|
27
|
+
end
|
28
|
+
|
29
|
+
def helper_methods # :nodoc:
|
30
|
+
@helper_methods
|
31
|
+
end
|
32
|
+
|
33
|
+
# Allows a subsclass to declare which datasets it uses.
|
34
|
+
#
|
35
|
+
# Dataset is designed to promote 'design by composition', rather than
|
36
|
+
# 'design by inheritance'. You should not use class hiearchies to share
|
37
|
+
# data and code in your datasets. Instead, you can write something like
|
38
|
+
# this:
|
39
|
+
#
|
40
|
+
# class PeopleDataset < Dataset::Base; end
|
41
|
+
# class DepartmentsDataset < Dataset::Base; end
|
42
|
+
# class OrganizationsDataset < Dataset::Base
|
43
|
+
# uses :people, :departments
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# When the OrganizationsDataset is loaded, it will have all the data
|
47
|
+
# from the datasets is uses, as well as all of the helper methods
|
48
|
+
# defined by those datasets.
|
49
|
+
#
|
50
|
+
# When a dataset uses other datasets, and those datasets themselves use
|
51
|
+
# datasets, things will be loaded in the order of dependency you would
|
52
|
+
# expect:
|
53
|
+
#
|
54
|
+
# C uses B
|
55
|
+
# A uses C
|
56
|
+
# B, C, A is the load order
|
57
|
+
#
|
58
|
+
def uses(*datasets)
|
59
|
+
@used_datasets = datasets
|
60
|
+
end
|
61
|
+
|
62
|
+
def used_datasets # :nodoc:
|
63
|
+
@used_datasets
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Invoked once before a collection of tests is run. If you use a dataset
|
68
|
+
# in multiple test classes, it will be called once for each of them -
|
69
|
+
# remember that the database will be cleared at the beginning of running a
|
70
|
+
# 'suite' or 'group' of tests, unless you are using nested contexts (as in
|
71
|
+
# nested describe blocks in RSpec).
|
72
|
+
#
|
73
|
+
# Override this method in your subclasses.
|
74
|
+
#
|
75
|
+
def load; end
|
76
|
+
end
|
77
|
+
|
78
|
+
# The easiest way to create some data before a suite of tests is run is by
|
79
|
+
# using a Dataset::Block. An example works wonders:
|
80
|
+
#
|
81
|
+
# class PeopleTest < Test::Unit::TestCase
|
82
|
+
# dataset do
|
83
|
+
# create_record :person, :billy, :name => 'Billy'
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# def test_name
|
87
|
+
# assert_equal 'Billy', people(:billy).name
|
88
|
+
# end
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# The database will be cleared and billy will be inserted once before
|
92
|
+
# running each of the tests within a transaction. All the normal transaction
|
93
|
+
# fixtures stuff will still work.
|
94
|
+
#
|
95
|
+
# One of the great features of Dataset, at least when things get really
|
96
|
+
# interesting in your data needs, is that nested contexts will be additive.
|
97
|
+
# Consider this:
|
98
|
+
#
|
99
|
+
# describe Something do
|
100
|
+
# dataset :a => Dataset :a is loaded (at the right time)
|
101
|
+
#
|
102
|
+
# it 'should whatever'
|
103
|
+
# end
|
104
|
+
#
|
105
|
+
# describe More do
|
106
|
+
# dataset :b => Dataset :b is loaded. :a data is still there
|
107
|
+
#
|
108
|
+
# it 'should'
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# describe Another do => Database is restored to :a, without re-running :a logic
|
113
|
+
# it 'should'
|
114
|
+
# end
|
115
|
+
# end
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
# == Instance Variables
|
119
|
+
#
|
120
|
+
# You may also assign instance variables in a dataset block, and they will
|
121
|
+
# be available to your test methods. You have to be careful with this in a
|
122
|
+
# similar way that you must with an RSpec before :all block. Since the
|
123
|
+
# instance variables are pointing to the same instances accross all tests,
|
124
|
+
# things can get weird if you intend to change their state. It's best use is
|
125
|
+
# for loading objects that you want to read a lot without loading over and
|
126
|
+
# over again for each test.
|
127
|
+
#
|
128
|
+
# == Building on Other Datasets
|
129
|
+
#
|
130
|
+
# You may pass any number of Dataset::Base subclasses - or better yet, their
|
131
|
+
# names - to the dataset method. When you use a block, this adds a lot of
|
132
|
+
# clarity:
|
133
|
+
#
|
134
|
+
# class PersonTest < Test::Unit::TestCase
|
135
|
+
# dataset :organization, :people do
|
136
|
+
# id = create_record :person, :second_admin, :name => 'Admin Three'
|
137
|
+
# create_record :organization_administratorship, :organization_id => organization_id(:first_bank), :person_id => id
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# def test_admins
|
141
|
+
# assert organizations(:first_bank).admins.include?(people(:second_admin))
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# == Reusing a Dataset
|
146
|
+
#
|
147
|
+
# When you need to go beyond the block, create a Dataset::Base subclass!
|
148
|
+
class Block < Base
|
149
|
+
include Dataset::InstanceMethods
|
150
|
+
|
151
|
+
def load # :nodoc:
|
152
|
+
dataset_session_binding.install_block_variables(self)
|
153
|
+
doload
|
154
|
+
dataset_session_binding.copy_block_variables(self)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|