fixture_background 0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +79 -0
- data/Rakefile +2 -0
- data/TODO +2 -0
- data/fixture_background.gemspec +21 -0
- data/lib/fixture_background.rb +6 -0
- data/lib/fixture_background/active_support/test_case.rb +58 -0
- data/lib/fixture_background/background.rb +44 -0
- data/lib/fixture_background/generator.rb +85 -0
- data/lib/fixture_background/shoulda.rb +63 -0
- data/lib/fixture_background/version.rb +4 -0
- metadata +77 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2011, tmp8 GmbH
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
4
|
+
obtaining a copy of this software and associated documentation
|
5
|
+
files (the "Software"), to deal in the Software without
|
6
|
+
restriction, including without limitation the rights to use,
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
copies of the Software, and to permit persons to whom the
|
9
|
+
Software is furnished to do so, subject to the following
|
10
|
+
conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
== Fixture Backgrounds
|
2
|
+
|
3
|
+
Generate fixtures from factories _in_ you testcode to speedup test-runs!
|
4
|
+
|
5
|
+
Requires shoulda 2.11.3 (exact version for now - sorry)
|
6
|
+
|
7
|
+
thies@tmp8.de 20110207
|
8
|
+
|
9
|
+
|
10
|
+
== Usage
|
11
|
+
|
12
|
+
test_helper.rb:
|
13
|
+
|
14
|
+
require 'fixture_background'
|
15
|
+
|
16
|
+
class ActiveSupport::TestCase
|
17
|
+
include ::FixtureBackground::ActiveSupport::TestCase
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
some_test.rb:
|
22
|
+
|
23
|
+
require 'test_helper'
|
24
|
+
|
25
|
+
class TestTest < ActiveSupport::TestCase
|
26
|
+
background do
|
27
|
+
@hase = Hase.create(:name => "bunny")
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with thies" do
|
31
|
+
background do
|
32
|
+
@thies = Person.create(:name => "thies")
|
33
|
+
end
|
34
|
+
|
35
|
+
should "be cool" do
|
36
|
+
assert @hase
|
37
|
+
assert @thies
|
38
|
+
assert_nil @manuel
|
39
|
+
assert_nil @norman
|
40
|
+
assert_equal 1, Person.count
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with manuel" do
|
44
|
+
background do
|
45
|
+
@manuel = Person.create(:name => "manuel")
|
46
|
+
end
|
47
|
+
|
48
|
+
should "be cool" do
|
49
|
+
assert @hase
|
50
|
+
assert @thies
|
51
|
+
assert @manuel
|
52
|
+
assert_nil @norman
|
53
|
+
assert_equal 2, Person.count
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with norman" do
|
57
|
+
background do
|
58
|
+
@norman = Person.create(:name => "norman")
|
59
|
+
end
|
60
|
+
|
61
|
+
should "be cool" do
|
62
|
+
assert @hase
|
63
|
+
assert @thies
|
64
|
+
assert @manuel
|
65
|
+
assert @norman
|
66
|
+
assert_equal 3, Person.count
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
should "nother truth" do
|
72
|
+
assert @hase
|
73
|
+
assert @thies
|
74
|
+
assert_nil @manuel
|
75
|
+
assert_nil @norman
|
76
|
+
assert_equal 1, Person.count
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/Rakefile
ADDED
data/TODO
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "fixture_background/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "fixture_background"
|
7
|
+
s.version = FixtureBackground::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Thies C. Arntzen", "Norman Timmler"]
|
10
|
+
s.email = ["dev+fixture_background@tmp8.de"]
|
11
|
+
s.homepage = "http://tmp8.de"
|
12
|
+
s.summary = %q{Generate fixtures from factories _in_ you testcode to speedup test-runs}
|
13
|
+
s.description = %q{Generate fixtures from factories _in_ you testcode to speedup test-runs}
|
14
|
+
|
15
|
+
# s.rubyforge_project = "my_gem"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module FixtureBackground
|
2
|
+
module ActiveSupport
|
3
|
+
module TestCase
|
4
|
+
extend ::ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
class_inheritable_accessor :background_ivar_cache
|
8
|
+
class_inheritable_accessor :active_record_fixture_cache_resetted
|
9
|
+
|
10
|
+
set_callback(:setup, :before, :reset_active_record_fixture_cache, {:prepend => true})
|
11
|
+
set_callback(:setup, :before, :setup_background_ivars)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def parent_fixture_background
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def fixture_background
|
20
|
+
@fixture_background
|
21
|
+
end
|
22
|
+
|
23
|
+
def background(&blk)
|
24
|
+
@fixture_background = FixtureBackground::Background.new(name, self, nil, blk)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module InstanceMethods
|
29
|
+
def setup_background_ivars
|
30
|
+
return unless File.exist?("#{fixture_path}/ivars.dump")
|
31
|
+
|
32
|
+
fill_background_ivar_cache unless background_ivar_cache
|
33
|
+
background_ivar_cache.each do |ivar, record|
|
34
|
+
# deep clone the object
|
35
|
+
instance_variable_set(ivar, Marshal.load(Marshal.dump(record)))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def fill_background_ivar_cache
|
40
|
+
bm = Benchmark.realtime do
|
41
|
+
self.background_ivar_cache = YAML.load_file("#{fixture_path}/ivars.dump")
|
42
|
+
background_ivar_cache.each do |ivar, (class_name, id)|
|
43
|
+
record = class_name.constantize.find(id)
|
44
|
+
self.background_ivar_cache[ivar] = record
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset_active_record_fixture_cache
|
50
|
+
return if active_record_fixture_cache_resetted
|
51
|
+
|
52
|
+
Fixtures.class_variable_set(:@@all_cached_fixtures, {})
|
53
|
+
self.active_record_fixture_cache_resetted = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module FixtureBackground
|
2
|
+
class Background
|
3
|
+
attr_reader :background_block
|
4
|
+
|
5
|
+
def initialize(full_class_name, test_unit_class, parent, blk)
|
6
|
+
@test_unit_class = test_unit_class
|
7
|
+
@full_class_name = full_class_name
|
8
|
+
@parent = parent
|
9
|
+
@background_block = blk
|
10
|
+
|
11
|
+
Generator.new(@full_class_name, background_signature, fixture_path, ancestors_and_own_background_blocks) unless background_valid?
|
12
|
+
end
|
13
|
+
|
14
|
+
def ancestors_and_own_background_blocks
|
15
|
+
(@parent ? @parent.ancestors_and_own_background_blocks : []) << @background_block
|
16
|
+
end
|
17
|
+
|
18
|
+
def background_valid?
|
19
|
+
(IO.read("#{fixture_path}/.version") rescue nil) == background_signature
|
20
|
+
false
|
21
|
+
end
|
22
|
+
|
23
|
+
def background_signature
|
24
|
+
stack = caller.reject { |line| line =~ Regexp.new(__FILE__) }
|
25
|
+
test_file_path = File.expand_path(stack.first.match(/^(.+\.rb):/)[1])
|
26
|
+
block_syntax = ''
|
27
|
+
IO.read(test_file_path).scan(/(?:\A|\n)([ \t]*)background\s(?:do|{)(.*?)\n\1end/m) do |match|
|
28
|
+
block_syntax << match[1].gsub(/\s+/, '')
|
29
|
+
end
|
30
|
+
Digest::MD5.hexdigest(block_syntax)
|
31
|
+
end
|
32
|
+
|
33
|
+
def fixture_path
|
34
|
+
Rails.root.to_s + "/test/backgrounds/#{@full_class_name.underscore}/"
|
35
|
+
end
|
36
|
+
|
37
|
+
def class_for_test
|
38
|
+
klass = Kernel.const_set(@full_class_name, Class.new(@test_unit_class))
|
39
|
+
klass.fixture_path = fixture_path
|
40
|
+
klass.fixtures :all
|
41
|
+
klass
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module FixtureBackground
|
2
|
+
class Generator
|
3
|
+
def initialize(fixture_name, version, background_dir, blocks)
|
4
|
+
@background_dir = background_dir
|
5
|
+
remove_background_dir
|
6
|
+
create_background_dir
|
7
|
+
|
8
|
+
transaction_with_rollback do
|
9
|
+
(ActiveRecord::Base.connection.tables - ["schema_migrations"]).each do |table_name|
|
10
|
+
klass = table_name.classify.constantize
|
11
|
+
klass.delete_all
|
12
|
+
end
|
13
|
+
|
14
|
+
bm = Benchmark.realtime do
|
15
|
+
dump_ivars do |klass|
|
16
|
+
blocks.each do |block|
|
17
|
+
klass.instance_eval(&block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
dump_fixtures
|
21
|
+
end
|
22
|
+
|
23
|
+
File.open("#{@background_dir}/.version", 'w+') do |f|
|
24
|
+
f.write version
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Instanciating #{fixture_name} took #{bm}ms"
|
28
|
+
end
|
29
|
+
rescue Exception
|
30
|
+
remove_background_dir
|
31
|
+
raise
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def transaction_with_rollback
|
36
|
+
ActiveRecord::Base.connection.increment_open_transactions
|
37
|
+
ActiveRecord::Base.connection.begin_db_transaction
|
38
|
+
yield
|
39
|
+
ActiveRecord::Base.connection.rollback_db_transaction
|
40
|
+
ActiveRecord::Base.connection.decrement_open_transactions
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_background_dir
|
44
|
+
FileUtils.mkdir_p(@background_dir)
|
45
|
+
end
|
46
|
+
|
47
|
+
def remove_background_dir
|
48
|
+
FileUtils.rm_rf(@background_dir)
|
49
|
+
end
|
50
|
+
|
51
|
+
def dump_ivars
|
52
|
+
klass = Class.new
|
53
|
+
existing_ivars = klass.instance_variables
|
54
|
+
|
55
|
+
yield klass
|
56
|
+
|
57
|
+
ivar_hash = {}
|
58
|
+
(klass.instance_variables - existing_ivars).each do |ivar|
|
59
|
+
record = klass.instance_variable_get(ivar)
|
60
|
+
ivar_hash[ivar.to_s] = [record.class.name, record.id] if record.class.respond_to? :find
|
61
|
+
end
|
62
|
+
|
63
|
+
File.open("#{@background_dir}/ivars.dump", 'w+') do |f|
|
64
|
+
YAML.dump(ivar_hash, f)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def dump_fixtures
|
69
|
+
(ActiveRecord::Base.connection.tables - ["schema_migrations"]).each do |table_name|
|
70
|
+
klass = table_name.classify.constantize
|
71
|
+
|
72
|
+
records = klass.all
|
73
|
+
|
74
|
+
fixtures = {}
|
75
|
+
records.each do |record|
|
76
|
+
fixtures[table_name + record.id.to_s] = record.attributes
|
77
|
+
end
|
78
|
+
|
79
|
+
File.open("#{@background_dir}/#{table_name}.yml", 'w+') do |f|
|
80
|
+
YAML.dump(fixtures, f)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Shoulda
|
2
|
+
raise "fixture_background is only compatible with shoulda 2.11.3 installed #{VERSION}" if VERSION != "2.11.3"
|
3
|
+
|
4
|
+
class Context
|
5
|
+
attr_reader :fixture_background
|
6
|
+
|
7
|
+
def full_class_name
|
8
|
+
(test_unit_class.name + full_name.gsub(/\s+/, '_')).camelcase
|
9
|
+
end
|
10
|
+
|
11
|
+
def parent_fixture_background
|
12
|
+
if parent && parent.respond_to?(:fixture_background)
|
13
|
+
parent.fixture_background || parent.parent_fixture_background
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def background(&blk)
|
18
|
+
@fixture_background = FixtureBackground::Background.new(full_class_name, test_unit_class, parent_fixture_background, blk)
|
19
|
+
end
|
20
|
+
|
21
|
+
def class_for_test
|
22
|
+
@fixture_background ? @fixture_background.class_for_test : test_unit_class
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
#
|
27
|
+
# the following functions are copied from shoulda/context.rb
|
28
|
+
#
|
29
|
+
|
30
|
+
def create_test_from_should_hash(klass, should)
|
31
|
+
test_name = ["test:", full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
|
32
|
+
|
33
|
+
if klass.instance_methods.include?(test_name.to_s)
|
34
|
+
warn " * WARNING: '#{test_name}' is already defined"
|
35
|
+
end
|
36
|
+
|
37
|
+
context = self
|
38
|
+
klass.send(:define_method, test_name) do
|
39
|
+
@shoulda_context = context
|
40
|
+
begin
|
41
|
+
context.run_parent_setup_blocks(self)
|
42
|
+
should[:before].bind(self).call if should[:before]
|
43
|
+
context.run_current_setup_blocks(self)
|
44
|
+
should[:block].bind(self).call
|
45
|
+
ensure
|
46
|
+
context.run_all_teardown_blocks(self)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def build
|
52
|
+
klass = class_for_test
|
53
|
+
|
54
|
+
shoulds.each do |should|
|
55
|
+
create_test_from_should_hash(klass, should)
|
56
|
+
end
|
57
|
+
|
58
|
+
subcontexts.each { |context| context.build }
|
59
|
+
|
60
|
+
print_should_eventuallys
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fixture_background
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 9
|
8
|
+
version: "0.9"
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Thies C. Arntzen
|
12
|
+
- Norman Timmler
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-01-07 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description: Generate fixtures from factories _in_ you testcode to speedup test-runs
|
22
|
+
email:
|
23
|
+
- dev+fixture_background@tmp8.de
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- Gemfile
|
33
|
+
- MIT-LICENSE
|
34
|
+
- README.rdoc
|
35
|
+
- Rakefile
|
36
|
+
- TODO
|
37
|
+
- fixture_background.gemspec
|
38
|
+
- lib/fixture_background.rb
|
39
|
+
- lib/fixture_background/active_support/test_case.rb
|
40
|
+
- lib/fixture_background/background.rb
|
41
|
+
- lib/fixture_background/generator.rb
|
42
|
+
- lib/fixture_background/shoulda.rb
|
43
|
+
- lib/fixture_background/version.rb
|
44
|
+
has_rdoc: true
|
45
|
+
homepage: http://tmp8.de
|
46
|
+
licenses: []
|
47
|
+
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
segments:
|
67
|
+
- 0
|
68
|
+
version: "0"
|
69
|
+
requirements: []
|
70
|
+
|
71
|
+
rubyforge_project:
|
72
|
+
rubygems_version: 1.3.7
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Generate fixtures from factories _in_ you testcode to speedup test-runs
|
76
|
+
test_files: []
|
77
|
+
|