fixturized 0.4.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/.document +5 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +9 -0
- data/LICENSE +20 -0
- data/README.markdown +110 -0
- data/Rakefile +32 -0
- data/VERSION +1 -0
- data/fixturized.gemspec +23 -0
- data/lib/database_handler.rb +100 -0
- data/lib/file_handler.rb +32 -0
- data/lib/fixturized.rb +18 -0
- data/lib/fixturized/version.rb +3 -0
- data/lib/global_methods.rb +7 -0
- data/lib/runner.rb +26 -0
- data/lib/wrapper.rb +57 -0
- data/spec/fixturized_spec.rb +328 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +23 -0
- metadata +80 -0
data/.document
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Jacek Szarski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
# fixturized [](http://travis-ci.org/szarski/Fixturized)
|
2
|
+
|
3
|
+
Fixturized makes your tests' data generation take less time.
|
4
|
+
|
5
|
+
Remember how fast fixtures used to work? But they were really painfull if you added one more after_save in your model - that filled some field in - and you had to update your fixture files.
|
6
|
+
|
7
|
+
FactoryGirl for instance is awesome because it gives you extreme flexibility. But it is also very slow if you save a lot of records to your db.
|
8
|
+
|
9
|
+
Fixturized is a solution in between fixtures and whatever you want, which means it will generate fixtures out of your FactoryGirl (or whatever you use) calls and refresh them if anything changes.
|
10
|
+
|
11
|
+
## usage
|
12
|
+
|
13
|
+
Let's say you want to speed up an existing test.
|
14
|
+
|
15
|
+
Test case like:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
|
19
|
+
describe User do
|
20
|
+
before :each do
|
21
|
+
@user = Factory :user
|
22
|
+
@dog = Factory :dog
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should know the dog's name" do
|
26
|
+
@user.get_dog @dog
|
27
|
+
@user.dog_name.should == @dog.name
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
```
|
32
|
+
|
33
|
+
Becomes:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
|
37
|
+
describe User do
|
38
|
+
before :each do
|
39
|
+
fixturized do |o|
|
40
|
+
o.user = Factory :user
|
41
|
+
o.dog = Factory :dog
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should know the dog's name" do
|
46
|
+
@user.get_dog @dog
|
47
|
+
@user.dog_name.should == @dog.name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
```
|
52
|
+
|
53
|
+
## the way it works
|
54
|
+
|
55
|
+
When fixturized gets a block it:
|
56
|
+
|
57
|
+
* check if fixtures exist for this block
|
58
|
+
|
59
|
+
If so:
|
60
|
+
|
61
|
+
* clears the database
|
62
|
+
* loads database content and variables
|
63
|
+
|
64
|
+
If not:
|
65
|
+
|
66
|
+
* clears the database
|
67
|
+
* runs the fixturized block
|
68
|
+
* dumps db content
|
69
|
+
* saves variable values
|
70
|
+
|
71
|
+
The first run will be slightly slower than usualy.
|
72
|
+
|
73
|
+
Each time the block's been changed, fixturized will generate the fixture for this particular block from stretch.
|
74
|
+
|
75
|
+
If you change your models in a way that affects their database layouts, you can just <pre>rm fixturized/*</pre> and it will create all the fixtures once again.
|
76
|
+
|
77
|
+
## drawbacks
|
78
|
+
|
79
|
+
There are two main problems with fixturized:
|
80
|
+
|
81
|
+
* you can not stack fixturized blocks (each erases the database)
|
82
|
+
* instead of using instance variables you need to use the Fixturized::Wrapper's methods:
|
83
|
+
|
84
|
+
```ruby
|
85
|
+
@user = Factory :user
|
86
|
+
```
|
87
|
+
|
88
|
+
becomes:
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
fixturized do |o|
|
92
|
+
o.user = Factory :user
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
## compatibility
|
97
|
+
|
98
|
+
Fixturized consits of several classes, each responsible for interactions with different interfaces:
|
99
|
+
|
100
|
+
* DatabaseHandler - clears database, dumps db, loads db content, loads db records
|
101
|
+
* FileHandler - reads and writes YAML files
|
102
|
+
* Runner - runs the fixturized block, determines whether fixtures are up to date, hooks up the Wrapper
|
103
|
+
* Wrapper - loads and saves all the data from the block using the rest of the modules
|
104
|
+
|
105
|
+
These classes currently support ActiveReord with an sql database and classic YAML fixtures.
|
106
|
+
To use different software you just need to replace one of the classes.
|
107
|
+
|
108
|
+
## Copyright
|
109
|
+
|
110
|
+
Copyright (c) 2010 Jacek Szarski. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler::GemHelper.install_tasks
|
3
|
+
|
4
|
+
|
5
|
+
begin
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
require "rspec/core/rake_task"
|
9
|
+
|
10
|
+
desc "Run all examples"
|
11
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
12
|
+
t.rspec_path = 'bin/rspec'
|
13
|
+
t.rspec_opts = %w[--color]
|
14
|
+
t.verbose = false
|
15
|
+
end
|
16
|
+
|
17
|
+
namespace :spec do
|
18
|
+
task :cleanup do
|
19
|
+
rm_rf 'coverage.data'
|
20
|
+
end
|
21
|
+
|
22
|
+
RSpec::Core::RakeTask.new :rcov do |t|
|
23
|
+
t.rcov = true
|
24
|
+
t.rcov_opts = %[-Ilib -Ispec --exclude "gems/*,features"]
|
25
|
+
t.verbose = false
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
rescue
|
31
|
+
puts 'Could not load RSpec Rake tasks'
|
32
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.4.0
|
data/fixturized.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "fixturized/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "fixturized"
|
7
|
+
s.version = Fixturized::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Jacek Szarski", "Marcin Bunsch"]
|
10
|
+
s.email = ["jacek@applicake.com"]
|
11
|
+
s.homepage = "https://github.com/szarski/Fixturized"
|
12
|
+
s.summary = %q{in between fixtures and whatever you want}
|
13
|
+
s.description = %q{in between fixtures and whatever you want}
|
14
|
+
|
15
|
+
s.rubyforge_project = "fixturized"
|
16
|
+
|
17
|
+
s.add_dependency "sourcify"
|
18
|
+
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Fixturized::DatabaseHandler
|
2
|
+
# This module handles all features related to the db (ActiveRecrod assumend).
|
3
|
+
# If you want to hook a different mapper, here's the place
|
4
|
+
|
5
|
+
# engine required methods:
|
6
|
+
#
|
7
|
+
# is_model?
|
8
|
+
# substitute_model(value)
|
9
|
+
# load_model(value)
|
10
|
+
# data_to_object
|
11
|
+
# object_to_data
|
12
|
+
# clear_all_tables
|
13
|
+
|
14
|
+
def engine
|
15
|
+
ActiveRecordAndMysqlEngine
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_model?(value)
|
19
|
+
self.engine.is_model? value
|
20
|
+
end
|
21
|
+
|
22
|
+
def substitute_model(value)
|
23
|
+
self.engine.substitute_model(value)
|
24
|
+
end
|
25
|
+
|
26
|
+
def load_model(value)
|
27
|
+
self.engine.load_model(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def collect_db_data
|
31
|
+
return self.engine.data_to_object
|
32
|
+
end
|
33
|
+
|
34
|
+
def write_db_data(data)
|
35
|
+
self.engine.object_to_data(data)
|
36
|
+
end
|
37
|
+
|
38
|
+
def clear_db
|
39
|
+
self.engine.clear_all_tables
|
40
|
+
end
|
41
|
+
|
42
|
+
module ActiveRecordAndMysqlEngine
|
43
|
+
|
44
|
+
def is_model?(value)
|
45
|
+
defined?(ActiveRecord::Base) and value.class.superclass == ActiveRecord::Base
|
46
|
+
end
|
47
|
+
|
48
|
+
def substitute_model(value)
|
49
|
+
return [value.class.to_s, value.id]
|
50
|
+
end
|
51
|
+
|
52
|
+
def load_model(value)
|
53
|
+
klass = eval value.first
|
54
|
+
id = value.last.to_i
|
55
|
+
return klass.find(id)
|
56
|
+
end
|
57
|
+
|
58
|
+
def clear_all_tables
|
59
|
+
interesting_tables.each do |tbl|
|
60
|
+
ActiveRecord::Base.connection.execute "DELETE FROM #{tbl}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def interesting_tables
|
65
|
+
ActiveRecord::Base.connection.tables.sort.reject do |tbl|
|
66
|
+
['schema_info', 'sessions', 'public_exceptions'].include?(tbl)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def object_to_data(objects)
|
71
|
+
objects.each do |tbl, fixtures|
|
72
|
+
unless fixtures.to_a.empty?
|
73
|
+
klass = tbl.classify.constantize
|
74
|
+
ActiveRecord::Base.transaction do
|
75
|
+
statement = "INSERT INTO #{tbl} (#{fixtures.first.keys.collect{|k| "`#{k}`"}.join(",")}) " + fixtures.collect do |fixture|
|
76
|
+
"(SELECT #{fixture.values.collect { |value| ActiveRecord::Base.connection.quote(value) }.join(', ')})"
|
77
|
+
end.join(" UNION ")
|
78
|
+
ActiveRecord::Base.connection.execute statement, 'Fixture Insert'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def data_to_object
|
85
|
+
objects = {}
|
86
|
+
interesting_tables.each do |tbl|
|
87
|
+
begin
|
88
|
+
klass = tbl.classify.constantize
|
89
|
+
objects[tbl] = klass.find(:all).collect(&:attributes)
|
90
|
+
rescue Exception
|
91
|
+
end
|
92
|
+
end
|
93
|
+
return objects
|
94
|
+
end
|
95
|
+
|
96
|
+
self.extend self
|
97
|
+
end
|
98
|
+
|
99
|
+
self.extend self
|
100
|
+
end
|
data/lib/file_handler.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Fixturized::FileHandler
|
2
|
+
# All filesystem operations are handled here
|
3
|
+
|
4
|
+
def fixture_dir
|
5
|
+
"#{RAILS_ROOT}/fixturized"
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_fixture_dir
|
9
|
+
if Dir[self.fixture_dir].empty?
|
10
|
+
FileUtils.mkdir_p self.fixture_dir
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_fixture(filename, objects)
|
15
|
+
Fixturized.create_fixture_dir
|
16
|
+
return File.open(self.fixture_path(filename), 'w') {|f| YAML.dump objects, f}
|
17
|
+
end
|
18
|
+
|
19
|
+
def load_fixture(filename)
|
20
|
+
return YAML.load_file(self.fixture_path(filename))
|
21
|
+
end
|
22
|
+
|
23
|
+
def fixture_exists?(filename)
|
24
|
+
return FileTest.exists?(self.fixture_path(filename))
|
25
|
+
end
|
26
|
+
|
27
|
+
def fixture_path(filename)
|
28
|
+
return File.join(self.fixture_dir, filename)
|
29
|
+
end
|
30
|
+
|
31
|
+
self.extend self
|
32
|
+
end
|
data/lib/fixturized.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fixturized
|
2
|
+
|
3
|
+
def self.create_fixture_dir
|
4
|
+
Fixturized::FileHandler.create_fixture_dir
|
5
|
+
end
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
# external requires:
|
10
|
+
require 'sourcify'
|
11
|
+
require 'digest/md5'
|
12
|
+
|
13
|
+
#internal requires:
|
14
|
+
require 'global_methods'
|
15
|
+
require 'runner'
|
16
|
+
require 'file_handler'
|
17
|
+
require 'database_handler'
|
18
|
+
require 'wrapper'
|
data/lib/runner.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
class Fixturized::Runner
|
2
|
+
def initialize(main_object=nil, &block)
|
3
|
+
Fixturized::DatabaseHandler.clear_db
|
4
|
+
@block = block
|
5
|
+
if Fixturized::FileHandler.fixture_exists?(self.filename)
|
6
|
+
data = Fixturized::FileHandler.load_fixture self.filename
|
7
|
+
Fixturized::DatabaseHandler.write_db_data(data[:database])
|
8
|
+
wrapper = Fixturized::Wrapper.new(data[:variables],data[:models])
|
9
|
+
wrapper.set_instance_variables_on(main_object)
|
10
|
+
else
|
11
|
+
wrapper = Fixturized::Wrapper.new
|
12
|
+
@block.call wrapper
|
13
|
+
Fixturized::FileHandler.write_fixture self.filename, {:database => Fixturized::DatabaseHandler.collect_db_data, :variables => wrapper.variables, :models => wrapper.models}
|
14
|
+
wrapper.set_instance_variables_on(main_object)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def filename
|
19
|
+
return "#{self.block_hash}.yml"
|
20
|
+
end
|
21
|
+
|
22
|
+
def block_hash
|
23
|
+
Digest::MD5.hexdigest(@block.to_source)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/wrapper.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
class Fixturized::Wrapper
|
2
|
+
attr_reader :variables, :models
|
3
|
+
|
4
|
+
def initialize(variables={},models={})
|
5
|
+
@variables = variables
|
6
|
+
@models = models
|
7
|
+
@loaded_models = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(method_name, *args)
|
11
|
+
if method_name.to_s =~ /.+=$/
|
12
|
+
raise Exception.new('too many arguments in assignment') unless args.size == 1
|
13
|
+
method_name = method_name.to_s.gsub(/=$/,'')
|
14
|
+
self.set(method_name, args.first)
|
15
|
+
else
|
16
|
+
raise Exception.new('unexpected arguments in retrieval') unless args.empty?
|
17
|
+
method_name = method_name.to_s
|
18
|
+
self.read method_name
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def set(name, value)
|
23
|
+
if Fixturized::DatabaseHandler.is_model?(value)
|
24
|
+
@models[name] = Fixturized::DatabaseHandler.substitute_model(value)
|
25
|
+
else
|
26
|
+
@variables[name] = value
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(name)
|
31
|
+
@variables[name] || read_model(name)
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_model(name)
|
35
|
+
loaded = @loaded_models[name.to_s]
|
36
|
+
value = @models[name.to_s]
|
37
|
+
if loaded
|
38
|
+
return loaded
|
39
|
+
elsif value
|
40
|
+
result = Fixturized::DatabaseHandler.load_model(value)
|
41
|
+
@loaded_models[name.to_s] = result
|
42
|
+
return result
|
43
|
+
else
|
44
|
+
return nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_instance_variables_on(object)
|
49
|
+
@variables.each do |name, value|
|
50
|
+
object.instance_variable_set "@#{name}", value
|
51
|
+
end
|
52
|
+
@models.each do |name, value|
|
53
|
+
object.instance_variable_set "@#{name}", read_model(name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,328 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
|
4
|
+
describe "Fixturized" do
|
5
|
+
before(:each) do
|
6
|
+
Fixturized::FileHandler.stubs(:fixture_dir).returns(TEMP_FIXTURE_DIR)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "file operations" do
|
10
|
+
before(:each) do
|
11
|
+
remove_temp_dir
|
12
|
+
end
|
13
|
+
after(:each) do
|
14
|
+
remove_temp_dir
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should set the fixtures path properly" do
|
18
|
+
Fixturized.create_fixture_dir
|
19
|
+
Dir[TEMP_FIXTURE_DIR].should_not be_empty
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create fixture files in the fixture dir" do
|
23
|
+
Fixturized::FileHandler.write_fixture("some_name", {:a => 3})
|
24
|
+
FileTest.exists?(File.join(TEMP_FIXTURE_DIR, 'some_name')).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should write and load proper data into and from fixtures" do
|
28
|
+
Fixturized::FileHandler.write_fixture "some_name", {:a => 3}
|
29
|
+
Fixturized::FileHandler.load_fixture("some_name").should == {:a => 3}
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should check if a file exists" do
|
33
|
+
Fixturized::FileHandler.fixture_exists?("some_name").should be_false
|
34
|
+
Fixturized.create_fixture_dir
|
35
|
+
FileUtils.touch(File.join(TEMP_FIXTURE_DIR, 'some_name'))
|
36
|
+
Fixturized::FileHandler.fixture_exists?("some_name").should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not mix fixtures up" do
|
40
|
+
Fixturized::FileHandler.write_fixture "some_name", {:a => 3}
|
41
|
+
Fixturized::FileHandler.write_fixture "some_other_name", {:a => 4}
|
42
|
+
Fixturized::FileHandler.load_fixture("some_name").should == {:a => 3}
|
43
|
+
Fixturized::FileHandler.load_fixture("some_other_name").should == {:a => 4}
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should overwrite files" do
|
47
|
+
Fixturized::FileHandler.write_fixture "some_name", {:a => 3}
|
48
|
+
Fixturized::FileHandler.write_fixture "some_name", {:a => 4}
|
49
|
+
Fixturized::FileHandler.load_fixture("some_name").should == {:a => 4}
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "working with tests" do
|
55
|
+
|
56
|
+
before(:each) do
|
57
|
+
Fixturized::FileHandler.stubs(:write_fixture).raises(Exception.new('write_fixture call not stubbed!'))
|
58
|
+
Fixturized::FileHandler.stubs(:load_fixture).raises(Exception.new('load_fixture call not stubbed!'))
|
59
|
+
Fixturized::DatabaseHandler.stubs(:collect_db_data)
|
60
|
+
Fixturized::DatabaseHandler.stubs(:clear_db)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should add the fixturized command" do
|
64
|
+
Fixturized::FileHandler.stubs(:write_fixture)
|
65
|
+
fixturized do
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should run the block first time" do
|
70
|
+
Fixturized::FileHandler.stubs(:write_fixture)
|
71
|
+
class A;end
|
72
|
+
A.expects(:method).once
|
73
|
+
fixturized do
|
74
|
+
A.method
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should create block hashes that are their code iniections" do
|
79
|
+
Fixturized::FileHandler.stubs(:write_fixture)
|
80
|
+
runner1 = Fixturized::Runner.new do
|
81
|
+
a=1
|
82
|
+
end
|
83
|
+
runner2 = Fixturized::Runner.new do
|
84
|
+
a=2
|
85
|
+
end
|
86
|
+
runner3 = Fixturized::Runner.new do
|
87
|
+
a=1
|
88
|
+
end
|
89
|
+
runner1.block_hash.should == runner3.block_hash
|
90
|
+
runner1.block_hash.should_not == runner2.block_hash
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should call write_fixture with the block hash name + '.yml' at first run" do
|
94
|
+
Fixturized::Runner.any_instance.stubs(:block_hash).returns("stubbed_block_hash")
|
95
|
+
Fixturized::FileHandler.expects(:write_fixture).with {|filename, objects| filename == "stubbed_block_hash.yml"}.once
|
96
|
+
fixturized do
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should call write_fixture with collected db data on first run" do
|
101
|
+
@fake_data = 1
|
102
|
+
Fixturized::DatabaseHandler.expects(:collect_db_data).once.returns(@fake_data)
|
103
|
+
Fixturized::FileHandler.expects(:write_fixture).once.with {|filename, objects| objects[:database] = @fake_data}
|
104
|
+
fixturized do
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should load fixture on second run" do
|
109
|
+
@fake_data = 1
|
110
|
+
Fixturized::Runner.any_instance.stubs(:block_hash).returns("stubbed_block_hash")
|
111
|
+
Fixturized::FileHandler.expects(:fixture_exists?).with("stubbed_block_hash.yml").returns(true)
|
112
|
+
Fixturized::FileHandler.expects(:load_fixture).once.returns({:database => @fake_data, :variables => {}, :models => {}})
|
113
|
+
Fixturized::DatabaseHandler.expects(:write_db_data).once.with(@fake_data)
|
114
|
+
fixturized do
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should pass instance variables on first run" do
|
119
|
+
Fixturized::FileHandler.stubs(:write_fixture)
|
120
|
+
fixturized do |o|
|
121
|
+
o.variable = 123
|
122
|
+
end
|
123
|
+
@variable.should == 123
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should load instance variables on second run" do
|
127
|
+
Fixturized::FileHandler.expects(:write_fixture).with {|name, content| content[:variables] == {"variable" => 123}}.once
|
128
|
+
Fixturized::FileHandler.expects(:load_fixture).returns(:variables => {:variable => 123}, :models => {})
|
129
|
+
fixturized do |o|
|
130
|
+
o.variable = 123
|
131
|
+
end
|
132
|
+
Fixturized::FileHandler.expects(:fixture_exists?).once.returns true
|
133
|
+
Fixturized::DatabaseHandler.expects(:write_db_data).once
|
134
|
+
@variable = nil
|
135
|
+
fixturized do |o|
|
136
|
+
o.variable = 123
|
137
|
+
end
|
138
|
+
@variable.should == 123
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "models" do
|
142
|
+
before(:each) do
|
143
|
+
class SomeModel
|
144
|
+
def id; 5; end
|
145
|
+
end
|
146
|
+
Fixturized::DatabaseHandler.stubs(:is_model?).with{|val| val.class == SomeModel}.returns(true)
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should retrieve objects on and after first run" do
|
150
|
+
Fixturized::FileHandler.expects(:write_fixture).with {|name, content| content[:models] == {"model" => ["SomeModel",5]}}.once
|
151
|
+
Fixturized::FileHandler.expects(:load_fixture).returns(:models => {"model" => ["SomeModel",5]}, :variables => {})
|
152
|
+
SomeModel.expects(:find).with(5).returns(SomeModel.new)
|
153
|
+
fixturized do |o|
|
154
|
+
o.model = SomeModel.new
|
155
|
+
end
|
156
|
+
Fixturized::FileHandler.expects(:fixture_exists?).once.returns true
|
157
|
+
Fixturized::DatabaseHandler.expects(:write_db_data).once
|
158
|
+
SomeModel.expects(:find).with(5).returns(SomeModel.new)
|
159
|
+
@model.class.should == SomeModel
|
160
|
+
@model.id.should == 5
|
161
|
+
@model = nil
|
162
|
+
fixturized do |o|
|
163
|
+
o.model = SomeModel.new
|
164
|
+
end
|
165
|
+
@model.class.should == SomeModel
|
166
|
+
@model.id.should == 5
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should cache models so they're not loaded unneccesairly" do
|
170
|
+
Fixturized::FileHandler.expects(:write_fixture)
|
171
|
+
SomeModel.expects(:find).with(5).returns(SomeModel.new).once
|
172
|
+
fixturized do |o|
|
173
|
+
o.model = SomeModel.new
|
174
|
+
a=o.model
|
175
|
+
a=o.model
|
176
|
+
a=o.model
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should request db clear on first and second run" do
|
181
|
+
Fixturized::FileHandler.stubs(:write_fixture)
|
182
|
+
Fixturized::DatabaseHandler.expects(:clear_db).twice
|
183
|
+
fixturized do
|
184
|
+
8
|
185
|
+
end
|
186
|
+
fixturized do
|
187
|
+
8
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "collecting data [DB related]" do
|
195
|
+
describe "interface" do
|
196
|
+
|
197
|
+
it "should have a method #engine that returns the engine class" do
|
198
|
+
Fixturized::DatabaseHandler.engine.should be_a(Module)
|
199
|
+
Fixturized::DatabaseHandler.engine.should be_a(Fixturized::DatabaseHandler::ActiveRecordAndMysqlEngine)
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "should forewart method to engine:" do
|
203
|
+
|
204
|
+
it "#collect_db_data" do
|
205
|
+
Fixturized::DatabaseHandler.engine.expects(:data_to_object).with()
|
206
|
+
Fixturized::DatabaseHandler.collect_db_data
|
207
|
+
end
|
208
|
+
|
209
|
+
it "#write_db_data" do
|
210
|
+
data = mock
|
211
|
+
Fixturized::DatabaseHandler.engine.expects(:object_to_data).with(data)
|
212
|
+
Fixturized::DatabaseHandler.write_db_data data
|
213
|
+
end
|
214
|
+
|
215
|
+
it "is_model?" do
|
216
|
+
model = mock
|
217
|
+
Fixturized::DatabaseHandler.engine.expects(:is_model?).with(model)
|
218
|
+
Fixturized::DatabaseHandler.is_model? model
|
219
|
+
end
|
220
|
+
|
221
|
+
it "#clear_db" do
|
222
|
+
Fixturized::DatabaseHandler.engine.expects(:clear_all_tables).with()
|
223
|
+
Fixturized::DatabaseHandler.clear_db
|
224
|
+
end
|
225
|
+
|
226
|
+
it "#substitute_model" do
|
227
|
+
model = mock
|
228
|
+
Fixturized::DatabaseHandler.engine.expects(:substitute_model).with(model)
|
229
|
+
Fixturized::DatabaseHandler.substitute_model model
|
230
|
+
end
|
231
|
+
|
232
|
+
it "#load_model" do
|
233
|
+
data = mock
|
234
|
+
Fixturized::DatabaseHandler.engine.expects(:load_model).with(data)
|
235
|
+
Fixturized::DatabaseHandler.load_model data
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "engines" do
|
241
|
+
describe Fixturized::DatabaseHandler::ActiveRecordAndMysqlEngine do
|
242
|
+
before(:all) do
|
243
|
+
pending
|
244
|
+
#TODO: hook db here
|
245
|
+
end
|
246
|
+
after(:all) do
|
247
|
+
#TODO: close db connection here
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
# def is_model?(value)
|
265
|
+
# defined?(ActiveRecord::Base) and value.class.superclass == ActiveRecord::Base
|
266
|
+
# def substitute_model(value)
|
267
|
+
# return [value.class.to_s, value.id]
|
268
|
+
# def load_model(value)
|
269
|
+
# klass = eval value.first
|
270
|
+
# id = value.last.to_i
|
271
|
+
# return klass.find(id)
|
272
|
+
# def clear_all_tables
|
273
|
+
# interesting_tables.each do |tbl|
|
274
|
+
# ActiveRecord::Base.connection.execute "DELETE FROM #{tbl}"
|
275
|
+
# end
|
276
|
+
# def interesting_tables
|
277
|
+
# ActiveRecord::Base.connection.tables.sort.reject do |tbl|
|
278
|
+
# ['schema_info', 'sessions', 'public_exceptions'].include?(tbl)
|
279
|
+
# end
|
280
|
+
# def object_to_data(objects)
|
281
|
+
# objects.each do |tbl, fixtures|
|
282
|
+
# unless fixtures.to_a.empty?
|
283
|
+
# klass = tbl.classify.constantize
|
284
|
+
# ActiveRecord::Base.transaction do
|
285
|
+
# statement = "INSERT INTO #{tbl} (#{fixtures.first.keys.collect{|k| "`#{k}`"}.join(",")}) " + fixtures.collect do |fixture|
|
286
|
+
# "(SELECT #{fixture.values.collect { |value| ActiveRecord::Base.connection.quote(value) }.join(', ')})"
|
287
|
+
# end.join(" UNION ")
|
288
|
+
# ActiveRecord::Base.connection.execute statement, 'Fixture Insert'
|
289
|
+
# end
|
290
|
+
# end
|
291
|
+
# end
|
292
|
+
# def data_to_object
|
293
|
+
# objects = {}
|
294
|
+
# interesting_tables.each do |tbl|
|
295
|
+
# begin
|
296
|
+
# klass = tbl.classify.constantize
|
297
|
+
# objects[tbl] = klass.find(:all).collect(&:attributes)
|
298
|
+
# rescue Exception
|
299
|
+
# end
|
300
|
+
# end
|
301
|
+
# return objects
|
302
|
+
# end
|
303
|
+
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
|
308
|
+
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
|
315
|
+
|
316
|
+
|
317
|
+
|
318
|
+
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
it "#clear_all_tables should remove all tables contents" do
|
324
|
+
end
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter ".bundle"
|
4
|
+
end
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
require 'fixturized'
|
9
|
+
require 'rspec'
|
10
|
+
require 'mocha'
|
11
|
+
|
12
|
+
TEMP_DIR = File.join(File.dirname(__FILE__),'..','temp')
|
13
|
+
TEMP_FIXTURE_DIR = File.join(TEMP_DIR,'fixtures')
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.mock_with :mocha
|
17
|
+
end
|
18
|
+
|
19
|
+
def remove_temp_dir
|
20
|
+
if Dir[TEMP_DIR]
|
21
|
+
FileUtils.rm_rf TEMP_DIR
|
22
|
+
end
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fixturized
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jacek Szarski
|
9
|
+
- Marcin Bunsch
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2011-06-06 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: sourcify
|
17
|
+
requirement: &2151886400 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2151886400
|
26
|
+
description: in between fixtures and whatever you want
|
27
|
+
email:
|
28
|
+
- jacek@applicake.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .document
|
34
|
+
- .gitignore
|
35
|
+
- .rspec
|
36
|
+
- .travis.yml
|
37
|
+
- Gemfile
|
38
|
+
- LICENSE
|
39
|
+
- README.markdown
|
40
|
+
- Rakefile
|
41
|
+
- VERSION
|
42
|
+
- fixturized.gemspec
|
43
|
+
- lib/database_handler.rb
|
44
|
+
- lib/file_handler.rb
|
45
|
+
- lib/fixturized.rb
|
46
|
+
- lib/fixturized/version.rb
|
47
|
+
- lib/global_methods.rb
|
48
|
+
- lib/runner.rb
|
49
|
+
- lib/wrapper.rb
|
50
|
+
- spec/fixturized_spec.rb
|
51
|
+
- spec/spec.opts
|
52
|
+
- spec/spec_helper.rb
|
53
|
+
homepage: https://github.com/szarski/Fixturized
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project: fixturized
|
73
|
+
rubygems_version: 1.8.5
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: in between fixtures and whatever you want
|
77
|
+
test_files:
|
78
|
+
- spec/fixturized_spec.rb
|
79
|
+
- spec/spec.opts
|
80
|
+
- spec/spec_helper.rb
|