fill 0.1.0
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/Manifest +12 -0
- data/README.rdoc +131 -0
- data/Rakefile +24 -0
- data/VERSION +1 -0
- data/fill.gemspec +30 -0
- data/lib/fill.rb +39 -0
- data/lib/fill/configure.rb +69 -0
- data/lib/fill/presenter.rb +67 -0
- data/lib/fill/procedure.rb +55 -0
- data/spec/fill_spec.rb +249 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +35 -0
- metadata +75 -0
data/Manifest
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
= Fill
|
2
|
+
|
3
|
+
Rails 2.3.4 introduced db/seeds. Basically that means that the rake task
|
4
|
+
"rake db:seed" will run db/seeds.rb, so you can have a centralized place
|
5
|
+
to prepare your database by adding seed data.
|
6
|
+
|
7
|
+
"Fill" takes this one step further and provides methods to easily define
|
8
|
+
data in db/seeds.rb. Here's how:
|
9
|
+
|
10
|
+
Fill.database do |db|
|
11
|
+
|
12
|
+
db.produce :projects do
|
13
|
+
10.times { Factory(:project) }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
(I use factory_girl here, do whatever you like off course)
|
19
|
+
|
20
|
+
Now, when running "rake db:seed", it'll delete all records in the Project
|
21
|
+
model and run the contents off the produce block. It'll also measure how
|
22
|
+
long it took, resulting in this output:
|
23
|
+
|
24
|
+
+-------+--------+---------+----------+
|
25
|
+
| After | Before | Models | Time |
|
26
|
+
+-------+--------+---------+----------+
|
27
|
+
| 10 | 0 | Project | 0.018627 |
|
28
|
+
+-------+--------+---------+----------+
|
29
|
+
|
30
|
+
You'll need to install hirb for this pretty output. Otherwise it won't print
|
31
|
+
out this pretty table. I recommend using Hirb anyway. Find it at
|
32
|
+
http://github.com/cldwalker/hirb
|
33
|
+
|
34
|
+
== Why?
|
35
|
+
|
36
|
+
At my company, we taught testers, customers and developers to use
|
37
|
+
webistrano and run the db:seed" rake task themselves. This way, they can
|
38
|
+
test and experiment as much as they want, and they easily reset the
|
39
|
+
database when they fucked it up.
|
40
|
+
|
41
|
+
== Usage
|
42
|
+
|
43
|
+
=== db.produce
|
44
|
+
|
45
|
+
By specifying a block, do whatever you need to fill a model.
|
46
|
+
|
47
|
+
Example:
|
48
|
+
|
49
|
+
db.produce :users, :memberships do
|
50
|
+
10.times do
|
51
|
+
user = Factory(:user)
|
52
|
+
membership = Factory(:membership, :user => user)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
Specify the models that you want. The models that you specified will be
|
57
|
+
emptied, which is handy if you're building relational models, like users
|
58
|
+
and their memberships.
|
59
|
+
|
60
|
+
The models are named *plural*.
|
61
|
+
|
62
|
+
=== db.fill
|
63
|
+
|
64
|
+
Provide a simple list of values.
|
65
|
+
|
66
|
+
Example
|
67
|
+
|
68
|
+
db.fill :projects, :name, "Foo", "Bar", "Baz", "etc"
|
69
|
+
|
70
|
+
For simple models with only one distinct attribute, you can just specify
|
71
|
+
the model, attribute and the values.
|
72
|
+
|
73
|
+
See also the iain/root_table plugin if you have many of these.
|
74
|
+
|
75
|
+
=== db.invoke
|
76
|
+
|
77
|
+
Invoke a rake task.
|
78
|
+
|
79
|
+
db.invoke "some:task", :projects
|
80
|
+
|
81
|
+
I use a seperate rake task whenever I need to import files. Of course you
|
82
|
+
can do that in the +db.produce+, but that clutters your seeds.rb.
|
83
|
+
|
84
|
+
=== Global options
|
85
|
+
|
86
|
+
These options work on all above mentioned methods.
|
87
|
+
|
88
|
+
==== :needs
|
89
|
+
|
90
|
+
Specify one or many dependencies, tables to be filled before filling the ones
|
91
|
+
you're specifying now.
|
92
|
+
|
93
|
+
Example
|
94
|
+
|
95
|
+
db.produce :memberships, :needs => :users do
|
96
|
+
User.all.each { |user| Factory(:membership, :user => user) }
|
97
|
+
end
|
98
|
+
|
99
|
+
==== :delete
|
100
|
+
|
101
|
+
Set to false if you don't want to delete all records before filling it.
|
102
|
+
|
103
|
+
Example:
|
104
|
+
|
105
|
+
db.invoke "import:zipcodes", :zips, :delete => false
|
106
|
+
|
107
|
+
In this example, the zipcodes import takes a long time to complete, so it
|
108
|
+
doesn't insert them when the database is already filled.
|
109
|
+
|
110
|
+
==== :name
|
111
|
+
|
112
|
+
The output uses Rails i18n methods to determine how the output calls the
|
113
|
+
models filled, but if you want to specify your own name, use this option.
|
114
|
+
|
115
|
+
Example:
|
116
|
+
|
117
|
+
db.produce :users, :name => "Accounts" do
|
118
|
+
....
|
119
|
+
end
|
120
|
+
|
121
|
+
== Installation
|
122
|
+
|
123
|
+
Add this to config/environment.rb:
|
124
|
+
|
125
|
+
config.gem "iain-fill", :lib => "fill", :source => "http://gems.github.com"
|
126
|
+
|
127
|
+
And run "+rake gems:install+" and you're done.
|
128
|
+
|
129
|
+
---
|
130
|
+
|
131
|
+
Made by Iain, http://iain.nl/, Released under the MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
desc "Run all specs in spec directory"
|
6
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
7
|
+
t.spec_opts = ['--options spec/spec.opts']
|
8
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'echoe'
|
14
|
+
Echoe.new('fill', File.read('VERSION').chomp) do |p|
|
15
|
+
p.description = "Simple DSL for filling (seeding) your database"
|
16
|
+
p.url = "http://github.com/iain/fill"
|
17
|
+
p.author = "iain"
|
18
|
+
p.email = "iain@iain.nl"
|
19
|
+
p.ignore_pattern = [ "pkg/*" ]
|
20
|
+
p.development_dependencies = []
|
21
|
+
p.runtime_dependencies = []
|
22
|
+
end
|
23
|
+
rescue LoadError
|
24
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/fill.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{fill}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["iain"]
|
9
|
+
s.date = %q{2009-09-25}
|
10
|
+
s.description = %q{Simple DSL for filling (seeding) your database}
|
11
|
+
s.email = %q{iain@iain.nl}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/fill.rb", "lib/fill/configure.rb", "lib/fill/presenter.rb", "lib/fill/procedure.rb"]
|
13
|
+
s.files = ["Manifest", "README.rdoc", "Rakefile", "VERSION", "fill.gemspec", "lib/fill.rb", "lib/fill/configure.rb", "lib/fill/presenter.rb", "lib/fill/procedure.rb", "spec/fill_spec.rb", "spec/spec.opts", "spec/spec_helper.rb"]
|
14
|
+
s.homepage = %q{http://github.com/iain/fill}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Fill", "--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{fill}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Simple DSL for filling (seeding) your database}
|
20
|
+
|
21
|
+
if s.respond_to? :specification_version then
|
22
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
+
s.specification_version = 3
|
24
|
+
|
25
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
26
|
+
else
|
27
|
+
end
|
28
|
+
else
|
29
|
+
end
|
30
|
+
end
|
data/lib/fill.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'activesupport'
|
2
|
+
require File.dirname(__FILE__) + '/fill/configure'
|
3
|
+
require File.dirname(__FILE__) + '/fill/presenter'
|
4
|
+
require File.dirname(__FILE__) + '/fill/procedure'
|
5
|
+
|
6
|
+
module Fill
|
7
|
+
|
8
|
+
VERSION = File.read(File.dirname(__FILE__) + '/../VERSION').chomp
|
9
|
+
|
10
|
+
class << self
|
11
|
+
|
12
|
+
|
13
|
+
attr_writer :out
|
14
|
+
def out
|
15
|
+
@out ||= STDOUT
|
16
|
+
end
|
17
|
+
|
18
|
+
def database
|
19
|
+
db = Configure.new
|
20
|
+
yield db
|
21
|
+
perform!(db)
|
22
|
+
end
|
23
|
+
|
24
|
+
def perform!(configuration)
|
25
|
+
bm = time { configuration.perform! }
|
26
|
+
out.puts Presenter
|
27
|
+
out.puts "Database filled in %.2f seconds" % bm
|
28
|
+
Presenter.clear!
|
29
|
+
end
|
30
|
+
|
31
|
+
def time
|
32
|
+
started_at = Time.now
|
33
|
+
yield
|
34
|
+
Time.now - started_at
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Configure
|
4
|
+
|
5
|
+
def produce(*models, &block)
|
6
|
+
options = models.extract_options!
|
7
|
+
needs = options.delete(:needs) || []
|
8
|
+
register models, Procedure.new(models, options, &block)
|
9
|
+
dependent models, needs
|
10
|
+
end
|
11
|
+
|
12
|
+
def fill(model, field, *values)
|
13
|
+
options = values.extract_options!
|
14
|
+
self.produce model, options do
|
15
|
+
values.each do |value|
|
16
|
+
model.to_s.singularize.camelize.constantize.create!(field => value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def invoke(task, *models)
|
22
|
+
self.produce *models do
|
23
|
+
Rake::Task[task].invoke
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def environment(env, which, options = {})
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def perform!
|
32
|
+
registered.each_key { |model| perform(model) }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def results
|
38
|
+
results = registered.values.uniq.compact.map { |data| data.to_hash }
|
39
|
+
end
|
40
|
+
|
41
|
+
def perform(model)
|
42
|
+
raise "No fill data provided for #{model}" unless registered.has_key? model
|
43
|
+
dependencies[model].each { |dep| perform(dep) } if dependencies.has_key? model
|
44
|
+
registered[model].perform!
|
45
|
+
end
|
46
|
+
|
47
|
+
def register(models, data)
|
48
|
+
models.each do |model|
|
49
|
+
registered.update model => data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def dependent(models, dependent)
|
54
|
+
models.each do |model|
|
55
|
+
dependencies.update model => [dependent].flatten
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def registered
|
60
|
+
@registered ||= {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def dependencies
|
64
|
+
@dependencies ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Presenter
|
4
|
+
|
5
|
+
def self.present(data)
|
6
|
+
presenter.add(data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.presenter
|
10
|
+
@presenter ||= new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.to_s
|
14
|
+
presenter.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.hirb?
|
18
|
+
require 'hirb'
|
19
|
+
true
|
20
|
+
rescue LoadError
|
21
|
+
false
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.clear!
|
25
|
+
@presenter = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def add(data)
|
29
|
+
presented.push(data) if data && !presented.include?(data)
|
30
|
+
end
|
31
|
+
|
32
|
+
def hirb?
|
33
|
+
self.class.hirb?
|
34
|
+
end
|
35
|
+
|
36
|
+
def presented
|
37
|
+
@presented ||= []
|
38
|
+
end
|
39
|
+
|
40
|
+
def presentable
|
41
|
+
presented.map(&:to_hash)
|
42
|
+
end
|
43
|
+
|
44
|
+
def present_with_hirb
|
45
|
+
Hirb::Helpers::Table.render(presentable, :description => false)
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
hirb? ? present_with_hirb : present_hash.join("\n")
|
50
|
+
end
|
51
|
+
|
52
|
+
def present_hash
|
53
|
+
presentable.map do |row|
|
54
|
+
format_row(row).join(" - ")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def format_row(row)
|
59
|
+
row.map do |key, value|
|
60
|
+
value = "%.2f" % value if key == "Time"
|
61
|
+
"#{key}: #{value}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Procedure
|
4
|
+
|
5
|
+
attr_accessor :block, :options
|
6
|
+
|
7
|
+
def initialize(models, options = {}, &block)
|
8
|
+
@block = block
|
9
|
+
@options = { :delete => true }.merge(options)
|
10
|
+
@models = models
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform!
|
14
|
+
@performed ||= perform
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
{ "Models" => human_models, "Before" => @before.join(', '), "After" => @after.join(', '), "Time" => @time }
|
19
|
+
end
|
20
|
+
|
21
|
+
def human_models
|
22
|
+
@human_models ||= (options[:name] || humanize_models)
|
23
|
+
end
|
24
|
+
|
25
|
+
def humanize_models
|
26
|
+
models.map { |model| i18n_name(model) }.join(', ')
|
27
|
+
end
|
28
|
+
|
29
|
+
def i18n_name(model)
|
30
|
+
model.respond_to?(:human_name) ? model.human_name : model.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete_all
|
34
|
+
models.map { |model| model.delete_all }
|
35
|
+
end
|
36
|
+
|
37
|
+
def models
|
38
|
+
@models.map { |model| model.to_s.singularize.camelize.constantize }
|
39
|
+
end
|
40
|
+
|
41
|
+
def count
|
42
|
+
models.map { |model| model.count }
|
43
|
+
end
|
44
|
+
|
45
|
+
def perform
|
46
|
+
@before = options[:delete] ? delete_all : count
|
47
|
+
@time = Fill.time { block.call }
|
48
|
+
@after = count
|
49
|
+
Presenter.present self
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/spec/fill_spec.rb
ADDED
@@ -0,0 +1,249 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe Fill do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Output.output = []
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "the the internal workings of db.produce" do
|
10
|
+
|
11
|
+
it "should perform the content only after the block is closed" do
|
12
|
+
# This is so that all dependencies can be initialized
|
13
|
+
# before anything is executed.
|
14
|
+
lambda {
|
15
|
+
Fill.database do |db|
|
16
|
+
lambda {
|
17
|
+
db.produce :projects do
|
18
|
+
throw :fill_executed
|
19
|
+
end
|
20
|
+
}.should_not throw_symbol(:fill_executed)
|
21
|
+
end
|
22
|
+
}.should throw_symbol(:fill_executed)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should count the records" do
|
26
|
+
mock(Project).count
|
27
|
+
produce!
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should delete all the records" do
|
31
|
+
mock(Project).delete_all
|
32
|
+
produce!
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should get the human name of a model" do
|
36
|
+
mock(Project).human_name
|
37
|
+
produce!
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should report the total time" do
|
41
|
+
produce!
|
42
|
+
Output.output.last.should =~ /\ADatabase filled in (.*) seconds\Z/
|
43
|
+
end
|
44
|
+
|
45
|
+
context "without hirb" do
|
46
|
+
|
47
|
+
before { mock(Fill::Presenter).hirb? { false } }
|
48
|
+
|
49
|
+
describe "output per model" do
|
50
|
+
|
51
|
+
before do
|
52
|
+
stub(Project).human_name { "FOOBAR" }
|
53
|
+
stub(Project).delete_all { 123456789 }
|
54
|
+
stub(Project).count { 987654321 }
|
55
|
+
produce!
|
56
|
+
end
|
57
|
+
|
58
|
+
subject { Output.output.first }
|
59
|
+
|
60
|
+
it { should =~ /Time: ([0-9.]+)/ }
|
61
|
+
it { should include("Before: 123456789") }
|
62
|
+
it { should include("After: 987654321") }
|
63
|
+
it { should include("Models: FOOBAR") }
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should count the time of the block" do
|
68
|
+
|
69
|
+
# Fill itself shouldn't take up more than 1 second
|
70
|
+
# so this test should return just about 1 second
|
71
|
+
# I _am_ sorry about this crude example ;)
|
72
|
+
|
73
|
+
produce! { sleep 1 } # zzzzzzzzzz
|
74
|
+
|
75
|
+
Output.output.first =~ /Time: ([0-9.]+)/
|
76
|
+
$1.to_i.should == 1
|
77
|
+
|
78
|
+
# Test total time, not in a seperate example to shorten testrun
|
79
|
+
Output.output.last =~ /([0-9.]+) seconds/
|
80
|
+
$1.to_i.should == 1
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should use hirb when possible" do
|
86
|
+
out = "---HIRB OUTPUT---"
|
87
|
+
mock(Fill::Presenter).hirb? { true }
|
88
|
+
mock(Hirb::Helpers::Table).render(is_a(Array), :description => false) { out }
|
89
|
+
produce!
|
90
|
+
Output.output.first.should == out
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "arguments for db.produce" do
|
96
|
+
|
97
|
+
describe "multiple models" do
|
98
|
+
|
99
|
+
after do
|
100
|
+
produce! :projects, :users, :memberships do
|
101
|
+
User.create
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it "calls delete_all on all models" do
|
106
|
+
mock(Project).delete_all
|
107
|
+
mock(User).delete_all
|
108
|
+
mock(Membership).delete_all
|
109
|
+
end
|
110
|
+
|
111
|
+
it "calls count on all models" do
|
112
|
+
mock(Project).count
|
113
|
+
mock(User).count
|
114
|
+
mock(Membership).count
|
115
|
+
end
|
116
|
+
|
117
|
+
it "calls human_name on all models" do
|
118
|
+
mock(Project).human_name
|
119
|
+
mock(User).human_name
|
120
|
+
mock(Membership).human_name
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should only execute the procedure once" do
|
124
|
+
mock(User).create.times(1)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "dependencies" do
|
130
|
+
|
131
|
+
it "should run dependencies first" do
|
132
|
+
# This works because the dont_allow should be executed AFTER
|
133
|
+
# the call was actually done! Similarly, the mock should be
|
134
|
+
# defined BEFORE it was done.
|
135
|
+
Fill.database do |db|
|
136
|
+
db.produce :users, :needs => :projects do
|
137
|
+
dont_allow(Project).create
|
138
|
+
User.create
|
139
|
+
end
|
140
|
+
db.produce :projects do
|
141
|
+
Project.create
|
142
|
+
mock(User).create
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should execute once, even with multiple dependencies" do
|
148
|
+
mock(User).create.times(1)
|
149
|
+
Fill.database do |db|
|
150
|
+
db.produce(:memberships, :needs => :users) {}
|
151
|
+
db.produce(:projects, :needs => :users) {}
|
152
|
+
db.produce(:users) { User.create }
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should handle multiple dependencies" do
|
157
|
+
Fill.database do |db|
|
158
|
+
db.produce(:memberships, :needs => [:users, :projects]) do
|
159
|
+
# Again, don't allow, because these should already have
|
160
|
+
# been executed before this block is executed.
|
161
|
+
dont_allow(Project).create
|
162
|
+
dont_allow(User).create
|
163
|
+
Membership.create # twice because mocked twice
|
164
|
+
Membership.create
|
165
|
+
end
|
166
|
+
db.produce(:projects, :needs => :users) do
|
167
|
+
Project.create
|
168
|
+
mock(Membership).create
|
169
|
+
dont_allow(User).create
|
170
|
+
end
|
171
|
+
db.produce(:users) do
|
172
|
+
User.create
|
173
|
+
mock(Project).create
|
174
|
+
mock(Membership).create
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "without hirb" do
|
180
|
+
|
181
|
+
before { stub(Fill::Presenter).hirb? { false } }
|
182
|
+
|
183
|
+
it "should join model names" do
|
184
|
+
mock(Project).human_name { "Projects" }
|
185
|
+
mock(User).human_name { "Accounts" }
|
186
|
+
produce! :projects, :users
|
187
|
+
Output.output.first.should include("Models: Projects, Accounts")
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should join before counts" do
|
191
|
+
mock(Project).delete_all { 1234 }
|
192
|
+
mock(User).delete_all { 4321 }
|
193
|
+
produce! :projects, :users
|
194
|
+
Output.output.first.should include("Before: 1234, 4321")
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should join before counts" do
|
198
|
+
mock(Project).count { 789 }
|
199
|
+
mock(User).count { 456 }
|
200
|
+
produce! :projects, :users
|
201
|
+
Output.output.first.should include("After: 789, 456")
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should add up times" do
|
205
|
+
produce! :projects, :users
|
206
|
+
Output.output.first.should =~ /Time: [0-9.][^,]/ # no comma, no join(',')
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
describe "names" do
|
214
|
+
|
215
|
+
before { stub(Fill::Presenter).hirb? { false } }
|
216
|
+
|
217
|
+
it "should override name" do
|
218
|
+
name = ":::MYNAME:::"
|
219
|
+
dont_allow(Project).human_name
|
220
|
+
produce! :projects, :name => name
|
221
|
+
Output.output.first.should include("Models: #{name}")
|
222
|
+
end
|
223
|
+
|
224
|
+
it "should override name with multiple models" do
|
225
|
+
name = ":::FOOBAR:::"
|
226
|
+
dont_allow(Project).human_name
|
227
|
+
dont_allow(User).human_name
|
228
|
+
dont_allow(Membership).human_name
|
229
|
+
produce! :projects, :users, :memberships, :name => name
|
230
|
+
Output.output.first.should include("Models: #{name}")
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
describe "delete option" do
|
236
|
+
|
237
|
+
it "should not delete with delete option to false" do
|
238
|
+
dont_allow(Project).delete_all
|
239
|
+
dont_allow(User).delete_all
|
240
|
+
mock(Project).count.times(2) # before and after
|
241
|
+
mock(User).count.times(2) # before and after
|
242
|
+
produce! :users, :projects, :delete => false
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/fill'
|
2
|
+
|
3
|
+
Spec::Runner.configure do |config|
|
4
|
+
config.mock_with :rr
|
5
|
+
end
|
6
|
+
|
7
|
+
def produce!(*args)
|
8
|
+
args = [:projects] if args.empty?
|
9
|
+
Fill.database do |db|
|
10
|
+
db.produce *args do
|
11
|
+
yield if block_given?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class ActiveRecordMimic
|
17
|
+
class << self
|
18
|
+
attr_reader :delete_all, :count, :create, :human_name
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Output
|
23
|
+
class << self
|
24
|
+
attr_accessor :output
|
25
|
+
def puts(string)
|
26
|
+
@output ||= []
|
27
|
+
@output << string.to_s
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Fill.out = Output
|
32
|
+
|
33
|
+
class User < ActiveRecordMimic; end
|
34
|
+
class Project < ActiveRecordMimic; end
|
35
|
+
class Membership < ActiveRecordMimic; end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fill
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- iain
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-25 00:00:00 +02:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Simple DSL for filling (seeding) your database
|
17
|
+
email: iain@iain.nl
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- lib/fill.rb
|
25
|
+
- lib/fill/configure.rb
|
26
|
+
- lib/fill/presenter.rb
|
27
|
+
- lib/fill/procedure.rb
|
28
|
+
files:
|
29
|
+
- Manifest
|
30
|
+
- README.rdoc
|
31
|
+
- Rakefile
|
32
|
+
- VERSION
|
33
|
+
- fill.gemspec
|
34
|
+
- lib/fill.rb
|
35
|
+
- lib/fill/configure.rb
|
36
|
+
- lib/fill/presenter.rb
|
37
|
+
- lib/fill/procedure.rb
|
38
|
+
- spec/fill_spec.rb
|
39
|
+
- spec/spec.opts
|
40
|
+
- spec/spec_helper.rb
|
41
|
+
has_rdoc: true
|
42
|
+
homepage: http://github.com/iain/fill
|
43
|
+
licenses: []
|
44
|
+
|
45
|
+
post_install_message:
|
46
|
+
rdoc_options:
|
47
|
+
- --line-numbers
|
48
|
+
- --inline-source
|
49
|
+
- --title
|
50
|
+
- Fill
|
51
|
+
- --main
|
52
|
+
- README.rdoc
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: "0"
|
60
|
+
version:
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "1.2"
|
66
|
+
version:
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project: fill
|
70
|
+
rubygems_version: 1.3.5
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: Simple DSL for filling (seeding) your database
|
74
|
+
test_files: []
|
75
|
+
|