fixture_replacement 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG.rdoc +720 -0
  3. data/GPL_LICENSE +674 -0
  4. data/MIT_LICENSE +22 -0
  5. data/README.rdoc +154 -0
  6. data/Rakefile +8 -0
  7. data/TODO.rdoc +22 -0
  8. data/VERSION +1 -0
  9. data/contributions.rdoc +48 -0
  10. data/etc/bug_reports/2007_09_28_linoj.txt +51 -0
  11. data/etc/google_analytics +6 -0
  12. data/etc/patches/2007_09_14_default_model_name_with_arguments.diff +26 -0
  13. data/etc/patches/2007_10_14_active_record_specs.diff +396 -0
  14. data/etc/patches/2007_10_14_protected_attributes.diff +26 -0
  15. data/etc/patches/2007_10_14_send_patch.diff +79 -0
  16. data/etc/patches/2007_10_14_spelling_error_in_comments.diff +13 -0
  17. data/etc/patches/2007_10_17_protected_attributes_second_go.diff +212 -0
  18. data/etc/patches/2007_10_18_README.diff +137 -0
  19. data/etc/patches/2007_10_19_readme_tweak.diff +12 -0
  20. data/etc/patches/2007_10_19_silence_migration.diff +12 -0
  21. data/etc/patches/2007_10_25_changed_classify_to_camelize.diff +38 -0
  22. data/etc/patches/2007_11_20_fixture_replacement_generator_should_not_reload_environment_or_boot.patch +13 -0
  23. data/etc/patches/2007_11_20_string_random_refactor_and_extension.patch +104 -0
  24. data/etc/patches/2007_11_20_string_random_refactor_and_extension_v2.patch +108 -0
  25. data/fixture_replacement.gemspec +126 -0
  26. data/lib/fixture_replacement.rb +16 -0
  27. data/lib/fixture_replacement/attribute_builder.rb +129 -0
  28. data/lib/fixture_replacement/class_methods.rb +45 -0
  29. data/lib/fixture_replacement/method_generator.rb +38 -0
  30. data/lib/fixture_replacement/version.rb +13 -0
  31. data/lib/fr.rb +1 -0
  32. data/philosophy_and_bugs.rdoc +128 -0
  33. data/rake_tasks/code_quality.rb +37 -0
  34. data/rake_tasks/docs.rb +59 -0
  35. data/rake_tasks/gem.rb +27 -0
  36. data/rake_tasks/specs.rb +7 -0
  37. data/rake_tasks/tests.rb +7 -0
  38. data/rake_tasks/website.rb +11 -0
  39. data/spec/fixture_replacement/attribute_builder_spec.rb +162 -0
  40. data/spec/fixture_replacement/fixture_replacement_spec.rb +96 -0
  41. data/spec/fixture_replacement/fixtures/classes.rb +78 -0
  42. data/spec/fixture_replacement/fr_spec.rb +7 -0
  43. data/spec/fixture_replacement/integration/attr_protected_attributes_spec.rb +71 -0
  44. data/spec/fixture_replacement/integration/attributes_for_with_invalid_keys_spec.rb +14 -0
  45. data/spec/fixture_replacement/integration/attributes_from_spec_without_block.rb +52 -0
  46. data/spec/fixture_replacement/integration/create_method_spec.rb +61 -0
  47. data/spec/fixture_replacement/integration/cyclic_dependency_spec.rb +32 -0
  48. data/spec/fixture_replacement/integration/default_warnings_spec.rb +29 -0
  49. data/spec/fixture_replacement/integration/extend_spec.rb +37 -0
  50. data/spec/fixture_replacement/integration/has_and_belongs_to_many_spec.rb +64 -0
  51. data/spec/fixture_replacement/integration/new_method_spec.rb +96 -0
  52. data/spec/fixture_replacement/integration/private_methods_spec.rb +43 -0
  53. data/spec/fixture_replacement/integration/public_methods_spec.rb +21 -0
  54. data/spec/fixture_replacement/integration/valid_attributes_spec.rb +41 -0
  55. data/spec/fixture_replacement/integration/validation_spec.rb +54 -0
  56. data/spec/fixture_replacement/regressions/2008_01_21_random_string_with_sti_spec.rb +71 -0
  57. data/spec/fixture_replacement/version_spec.rb +7 -0
  58. data/spec/spec.opts +1 -0
  59. data/spec/spec_helper.rb +16 -0
  60. data/spec/spec_helpers.rb +117 -0
  61. data/test/test_helper.rb +21 -0
  62. data/test/unit/user_test.rb +57 -0
  63. metadata +143 -0
@@ -0,0 +1,12 @@
1
+ Index: README
2
+ ===================================================================
3
+ --- README (revision 65)
4
+ +++ README (working copy)
5
+ @@ -144,7 +144,6 @@
6
+ - default_* methods can take a hash (applied in rev. 11)
7
+ - Wincent Colaiuta (Huge Thanks)
8
+ - patch for spelling error in comments (applied in revision 31)
9
+ - - extra documentation (http://wincent.com/knowledge-base/FixtureReplacement)
10
+ - patch for specs with sqlite3 (applied in revision 35)
11
+ - patch to ignore attr_protected in mass assignment (applied in revision 57)
12
+ - README Documentation (applied in revision 62)
@@ -0,0 +1,12 @@
1
+ Index: spec/spec_helper.rb
2
+ ===================================================================
3
+ --- spec/spec_helper.rb (revision 65)
4
+ +++ spec/spec_helper.rb (working copy)
5
+ @@ -5,6 +5,7 @@
6
+
7
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
8
+
9
+ +ActiveRecord::Migration.verbose = false
10
+ ActiveRecord::Schema.define do
11
+
12
+ create_table :users do |t|
@@ -0,0 +1,38 @@
1
+ Index: lib/fixture_replacement/fixture_replacement.rb
2
+ ===================================================================
3
+ --- lib/fixture_replacement/fixture_replacement.rb (revision 70)
4
+ +++ lib/fixture_replacement/fixture_replacement.rb (working copy)
5
+ @@ -40,7 +40,7 @@
6
+
7
+ def initialize(method_name, fixture_mod=FixtureReplacement)
8
+ @model_name = method_name
9
+ - @model_class = method_name.classify
10
+ + @model_class = method_name.camelize
11
+ @fixture_module = fixture_mod
12
+
13
+ add_to_class_singleton(@model_class)
14
+ Index: spec/fixture_replacement/fixture_replacement_spec.rb
15
+ ===================================================================
16
+ --- spec/fixture_replacement/fixture_replacement_spec.rb (revision 70)
17
+ +++ spec/fixture_replacement/fixture_replacement_spec.rb (working copy)
18
+ @@ -14,6 +14,7 @@
19
+ end
20
+
21
+ class Gender < ActiveRecord::Base; end
22
+ +class Actress < ActiveRecord::Base; end
23
+
24
+
25
+
26
+ @@ -118,6 +119,12 @@
27
+ }.should raise_error
28
+ end
29
+
30
+ + it "should not raise an error if the model ends with 's'" do
31
+ + lambda {
32
+ + Generator.new("actress")
33
+ + }.should_not raise_error
34
+ + end
35
+ +
36
+ it "should be able to respond to generate_default_method" do
37
+ @generator.should respond_to(:generate_default_method)
38
+ end
@@ -0,0 +1,13 @@
1
+ Index: vendor/plugins/fixture_replacement/generators/fixture_replacement/fixture_replacement_generator.rb
2
+ ===================================================================
3
+ --- vendor/plugins/fixture_replacement/generators/fixture_replacement/fixture_replacement_generator.rb (revision 83)
4
+ +++ vendor/plugins/fixture_replacement/generators/fixture_replacement/fixture_replacement_generator.rb (working copy)
5
+ @@ -1,6 +1,6 @@
6
+ require 'rbconfig'
7
+ -require 'config/boot'
8
+ -require 'config/environment'
9
+ +require 'config/environment' unless RAILS_GEM_VERSION
10
+ +require 'config/boot' unless RAILS_ROOT
11
+
12
+ class FixtureReplacementGenerator < Rails::Generator::Base
13
+ DEFAULT_SHEBANG = File.join(Config::CONFIG['bindir'],
@@ -0,0 +1,104 @@
1
+ Index: lib/fixture_replacement/string.rb
2
+ ===================================================================
3
+ --- lib/fixture_replacement/string.rb (revision 83)
4
+ +++ lib/fixture_replacement/string.rb (working copy)
5
+ @@ -1,10 +1,21 @@
6
+ +class String
7
+ + def random_chr
8
+ + self[rand(size)].chr
9
+ + end
10
+ +
11
+ + def random_str(length=10)
12
+ + (1..length).collect {random_chr}.join
13
+ + end
14
+ +
15
+ + def formatted_random_str(format, length=10)
16
+ + format.split(/(%s)/).map {|str| str.sub('%s', random_str(length))}.join
17
+ + end
18
+
19
+ -class String
20
+ def self.random(length=10)
21
+ - chars = ("a".."z").to_a
22
+ - string = ""
23
+ - 1.upto(length) { |i| string << chars[rand(chars.size-1)]}
24
+ - return string
25
+ + ("a".."z").sort.join.random_str(length)
26
+ end
27
+ +
28
+ + def self.formatted_random(format, length=10)
29
+ + ("a".."z").sort.join.formatted_random_str(format, length)
30
+ + end
31
+ end
32
+ -
33
+ Index: spec/fixture_replacement/extentions_spec.rb
34
+ ===================================================================
35
+ --- spec/fixture_replacement/extentions_spec.rb (revision 83)
36
+ +++ spec/fixture_replacement/extentions_spec.rb (working copy)
37
+ @@ -2,7 +2,9 @@
38
+
39
+ describe "String.random" do
40
+ it "should not be the same as another randomly generated string" do
41
+ - String.random.should_not == String.random
42
+ + (1..100).each do |ctr|
43
+ + String.random.should_not == String.random
44
+ + end
45
+ end
46
+
47
+ it "should by default be 10 characters long" do
48
+ @@ -12,9 +14,51 @@
49
+ it "should be able to specify the length of the random string" do
50
+ String.random(100).size.should == 100
51
+ end
52
+ -
53
+ +
54
+ it "should only generate lowercase letters" do
55
+ - s = String.random(100)
56
+ - s.upcase.should == s.swapcase
57
+ + String.random(100).should =~ /^[a-z]{100}/
58
+ end
59
+ -end
60
+
61
+ +end
62
+ +
63
+ +describe "String.formatted_random" do
64
+ + it "should require a format argument to be given" do
65
+ + lambda { String.formatted_random }.should raise_error(ArgumentError)
66
+ + end
67
+ +
68
+ + it "should be able to generate simple formatted random strings" do
69
+ + String.formatted_random('%s@%s.%s').should =~ /^[a-z]{10}@[a-z]{10}\.[a-z]{10}$/
70
+ + end
71
+ +end
72
+ +
73
+ +describe "String#random_chr" do
74
+ + before(:each) do
75
+ + @string = "abcde"
76
+ + end
77
+ +
78
+ + it "should always provide a random character from the string" do
79
+ + (1..100).each do |ctr|
80
+ + @string.include?(@string.random_chr).should be_true
81
+ + end
82
+ + end
83
+ +
84
+ + it "should rarely generate the same character twice in a row given a very large, random distribution" do
85
+ + string = String.random(100)
86
+ + ctr = 0
87
+ + (1..100).each do |i|
88
+ + string.random_chr == string.random_chr && ctr += 1
89
+ + end
90
+ + ctr.should < 10
91
+ + end
92
+ +end
93
+ +
94
+ +describe "String#random_str" do
95
+ + it "should be able to generate random strings from a given string of characters" do
96
+ + "Jim Beth Sam Cassie".random_str(100).should =~ /^[ BCJSaehimst]{100}$/
97
+ + end
98
+ +end
99
+ +
100
+ +describe "String#formatted_random_str" do
101
+ + it "should be able to generate random strings from a given string of characters" do
102
+ + "Jim Beth Sam Cassie".formatted_random_str('%s@%s.%s').should =~ /^[ BCJSaehimst]{10}@[ BCJSaehimst]{10}\.[ BCJSaehimst]{10}$/
103
+ + end
104
+ +end
@@ -0,0 +1,108 @@
1
+ Index: lib/fixture_replacement/string.rb
2
+ ===================================================================
3
+ --- lib/fixture_replacement/string.rb (revision 83)
4
+ +++ lib/fixture_replacement/string.rb (working copy)
5
+ @@ -1,10 +1,25 @@
6
+ +class String
7
+ + def random_chr
8
+ + self[rand(size)].chr
9
+ + end
10
+ +
11
+ + def random_str(length=10)
12
+ + (1..length).collect {random_chr}.join
13
+ + end
14
+ +
15
+ + def formatted_random_str(format, length=10)
16
+ + result = format.dup
17
+ + while result.match(/(%(\d*)s)/) do
18
+ + result.sub!($1, random_str($2.empty? ? length : $2.to_i))
19
+ + end
20
+ + result
21
+ + end
22
+
23
+ -class String
24
+ def self.random(length=10)
25
+ - chars = ("a".."z").to_a
26
+ - string = ""
27
+ - 1.upto(length) { |i| string << chars[rand(chars.size-1)]}
28
+ - return string
29
+ + ("a".."z").sort.join.random_str(length)
30
+ end
31
+ +
32
+ + def self.formatted_random(format, length=10)
33
+ + ("a".."z").sort.join.formatted_random_str(format, length)
34
+ + end
35
+ end
36
+ -
37
+ Index: spec/fixture_replacement/extentions_spec.rb
38
+ ===================================================================
39
+ --- spec/fixture_replacement/extentions_spec.rb (revision 83)
40
+ +++ spec/fixture_replacement/extentions_spec.rb (working copy)
41
+ @@ -2,7 +2,9 @@
42
+
43
+ describe "String.random" do
44
+ it "should not be the same as another randomly generated string" do
45
+ - String.random.should_not == String.random
46
+ + (1..100).each do |ctr|
47
+ + String.random.should_not == String.random
48
+ + end
49
+ end
50
+
51
+ it "should by default be 10 characters long" do
52
+ @@ -12,9 +14,51 @@
53
+ it "should be able to specify the length of the random string" do
54
+ String.random(100).size.should == 100
55
+ end
56
+ -
57
+ +
58
+ it "should only generate lowercase letters" do
59
+ - s = String.random(100)
60
+ - s.upcase.should == s.swapcase
61
+ + String.random(100).should =~ /^[a-z]{100}/
62
+ end
63
+ -end
64
+
65
+ +end
66
+ +
67
+ +describe "String.formatted_random" do
68
+ + it "should require a format argument to be given" do
69
+ + lambda { String.formatted_random }.should raise_error(ArgumentError)
70
+ + end
71
+ +
72
+ + it "should be able to generate simple formatted random strings" do
73
+ + String.formatted_random('%s@%s.%s').should =~ /^[a-z]{10}@[a-z]{10}\.[a-z]{10}$/
74
+ + end
75
+ +end
76
+ +
77
+ +describe "String#random_chr" do
78
+ + before(:each) do
79
+ + @string = "abcde"
80
+ + end
81
+ +
82
+ + it "should always provide a random character from the string" do
83
+ + (1..100).each do |ctr|
84
+ + @string.include?(@string.random_chr).should be_true
85
+ + end
86
+ + end
87
+ +
88
+ + it "should rarely generate the same character twice in a row given a very large, random distribution" do
89
+ + string = String.random(100)
90
+ + ctr = 0
91
+ + (1..100).each do |i|
92
+ + string.random_chr == string.random_chr && ctr += 1
93
+ + end
94
+ + ctr.should < 10
95
+ + end
96
+ +end
97
+ +
98
+ +describe "String#random_str" do
99
+ + it "should be able to generate random strings from a given string of characters" do
100
+ + "Jim Beth Sam Cassie".random_str(100).should =~ /^[ BCJSaehimst]{100}$/
101
+ + end
102
+ +end
103
+ +
104
+ +describe "String#formatted_random_str" do
105
+ + it "should be able to generate random strings from a given string of characters" do
106
+ + "Jim Beth Sam Cassie".formatted_random_str('%s@%s.%s').should =~ /^[ BCJSaehimst]{10}@[ BCJSaehimst]{10}\.[ BCJSaehimst]{10}$/
107
+ + end
108
+ +end
@@ -0,0 +1,126 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{fixture_replacement}
8
+ s.version = "3.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Scott Taylor"]
12
+ s.date = %q{2009-11-21}
13
+ s.description = %q{FixtureReplacement is a Rails plugin that provides a simple way to
14
+ quickly populate your test database with model objects without having to manage multiple,
15
+ brittle fixture files. You can easily set up complex object graphs (with models which
16
+ reference other models) and add new objects on the fly.
17
+ }
18
+ s.email = %q{scott@railsnewbie.com}
19
+ s.extra_rdoc_files = [
20
+ "README.rdoc"
21
+ ]
22
+ s.files = [
23
+ ".gitignore",
24
+ "CHANGELOG.rdoc",
25
+ "GPL_LICENSE",
26
+ "MIT_LICENSE",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "TODO.rdoc",
30
+ "VERSION",
31
+ "contributions.rdoc",
32
+ "etc/bug_reports/2007_09_28_linoj.txt",
33
+ "etc/google_analytics",
34
+ "etc/patches/2007_09_14_default_model_name_with_arguments.diff",
35
+ "etc/patches/2007_10_14_active_record_specs.diff",
36
+ "etc/patches/2007_10_14_protected_attributes.diff",
37
+ "etc/patches/2007_10_14_send_patch.diff",
38
+ "etc/patches/2007_10_14_spelling_error_in_comments.diff",
39
+ "etc/patches/2007_10_17_protected_attributes_second_go.diff",
40
+ "etc/patches/2007_10_18_README.diff",
41
+ "etc/patches/2007_10_19_readme_tweak.diff",
42
+ "etc/patches/2007_10_19_silence_migration.diff",
43
+ "etc/patches/2007_10_25_changed_classify_to_camelize.diff",
44
+ "etc/patches/2007_11_20_fixture_replacement_generator_should_not_reload_environment_or_boot.patch",
45
+ "etc/patches/2007_11_20_string_random_refactor_and_extension.patch",
46
+ "etc/patches/2007_11_20_string_random_refactor_and_extension_v2.patch",
47
+ "fixture_replacement.gemspec",
48
+ "lib/fixture_replacement.rb",
49
+ "lib/fixture_replacement/attribute_builder.rb",
50
+ "lib/fixture_replacement/class_methods.rb",
51
+ "lib/fixture_replacement/method_generator.rb",
52
+ "lib/fixture_replacement/version.rb",
53
+ "lib/fr.rb",
54
+ "philosophy_and_bugs.rdoc",
55
+ "rake_tasks/code_quality.rb",
56
+ "rake_tasks/docs.rb",
57
+ "rake_tasks/gem.rb",
58
+ "rake_tasks/specs.rb",
59
+ "rake_tasks/tests.rb",
60
+ "rake_tasks/website.rb",
61
+ "spec/fixture_replacement/attribute_builder_spec.rb",
62
+ "spec/fixture_replacement/fixture_replacement_spec.rb",
63
+ "spec/fixture_replacement/fixtures/classes.rb",
64
+ "spec/fixture_replacement/fr_spec.rb",
65
+ "spec/fixture_replacement/integration/attr_protected_attributes_spec.rb",
66
+ "spec/fixture_replacement/integration/attributes_for_with_invalid_keys_spec.rb",
67
+ "spec/fixture_replacement/integration/attributes_from_spec_without_block.rb",
68
+ "spec/fixture_replacement/integration/create_method_spec.rb",
69
+ "spec/fixture_replacement/integration/cyclic_dependency_spec.rb",
70
+ "spec/fixture_replacement/integration/default_warnings_spec.rb",
71
+ "spec/fixture_replacement/integration/extend_spec.rb",
72
+ "spec/fixture_replacement/integration/has_and_belongs_to_many_spec.rb",
73
+ "spec/fixture_replacement/integration/new_method_spec.rb",
74
+ "spec/fixture_replacement/integration/private_methods_spec.rb",
75
+ "spec/fixture_replacement/integration/public_methods_spec.rb",
76
+ "spec/fixture_replacement/integration/valid_attributes_spec.rb",
77
+ "spec/fixture_replacement/integration/validation_spec.rb",
78
+ "spec/fixture_replacement/regressions/2008_01_21_random_string_with_sti_spec.rb",
79
+ "spec/fixture_replacement/version_spec.rb",
80
+ "spec/spec.opts",
81
+ "spec/spec_helper.rb",
82
+ "spec/spec_helpers.rb",
83
+ "test/test_helper.rb",
84
+ "test/unit/user_test.rb"
85
+ ]
86
+ s.homepage = %q{http://replacefixtures.rubyforge.org}
87
+ s.rdoc_options = ["--charset=UTF-8"]
88
+ s.require_paths = ["lib"]
89
+ s.rubygems_version = %q{1.3.5}
90
+ s.summary = %q{The original fixture replacement solution for rails}
91
+ s.test_files = [
92
+ "spec/fixture_replacement/attribute_builder_spec.rb",
93
+ "spec/fixture_replacement/fixture_replacement_spec.rb",
94
+ "spec/fixture_replacement/fixtures/classes.rb",
95
+ "spec/fixture_replacement/fr_spec.rb",
96
+ "spec/fixture_replacement/integration/attr_protected_attributes_spec.rb",
97
+ "spec/fixture_replacement/integration/attributes_for_with_invalid_keys_spec.rb",
98
+ "spec/fixture_replacement/integration/attributes_from_spec_without_block.rb",
99
+ "spec/fixture_replacement/integration/create_method_spec.rb",
100
+ "spec/fixture_replacement/integration/cyclic_dependency_spec.rb",
101
+ "spec/fixture_replacement/integration/default_warnings_spec.rb",
102
+ "spec/fixture_replacement/integration/extend_spec.rb",
103
+ "spec/fixture_replacement/integration/has_and_belongs_to_many_spec.rb",
104
+ "spec/fixture_replacement/integration/new_method_spec.rb",
105
+ "spec/fixture_replacement/integration/private_methods_spec.rb",
106
+ "spec/fixture_replacement/integration/public_methods_spec.rb",
107
+ "spec/fixture_replacement/integration/valid_attributes_spec.rb",
108
+ "spec/fixture_replacement/integration/validation_spec.rb",
109
+ "spec/fixture_replacement/regressions/2008_01_21_random_string_with_sti_spec.rb",
110
+ "spec/fixture_replacement/version_spec.rb",
111
+ "spec/spec_helper.rb",
112
+ "spec/spec_helpers.rb",
113
+ "test/test_helper.rb",
114
+ "test/unit/user_test.rb"
115
+ ]
116
+
117
+ if s.respond_to? :specification_version then
118
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
119
+ s.specification_version = 3
120
+
121
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
122
+ else
123
+ end
124
+ else
125
+ end
126
+ end
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift File.expand_path(File.join(File.dirname(__FILE__), "."))
2
+ load "fixture_replacement/version.rb"
3
+ load "fixture_replacement/class_methods.rb"
4
+ load "fixture_replacement/attribute_builder.rb"
5
+ load "fixture_replacement/method_generator.rb"
6
+
7
+ module FixtureReplacement
8
+ class InvalidInstance < StandardError; end
9
+
10
+ include FixtureReplacement::Version
11
+ extend FixtureReplacement::ClassMethods
12
+ end
13
+
14
+ load "fr.rb"
15
+
16
+ FixtureReplacement.load_example_data
@@ -0,0 +1,129 @@
1
+ module FixtureReplacement
2
+ class AttributeBuilder
3
+ class << self
4
+ def validate_instances!
5
+ instances.each do |fixture|
6
+ fixture.validate!
7
+ end
8
+
9
+ true
10
+ end
11
+
12
+ def instances
13
+ @instances ||= []
14
+ end
15
+
16
+ def add_instance(instance)
17
+ instances << instance
18
+ end
19
+
20
+ def clear_out_instances!
21
+ @instances = nil
22
+ end
23
+
24
+ def find_by_fixture_name(arg)
25
+ instances.detect { |instance| instance.fixture_name == arg }
26
+ end
27
+ end
28
+
29
+ def initialize(fixture_name, options={}, &block)
30
+ options.symbolize_keys!
31
+
32
+ check_valid_keys(options, [:from, :class])
33
+
34
+ @fixture_name = fixture_name.to_sym
35
+ @attributes_proc = block || lambda {}
36
+ @from = options[:from].to_sym if options.has_key?(:from)
37
+ @class = options[:class]
38
+
39
+ self.class.add_instance(self)
40
+ end
41
+
42
+ attr_reader :fixture_name
43
+ attr_reader :from
44
+
45
+ def active_record_class
46
+ @active_record_class ||= find_active_record_class
47
+ end
48
+
49
+ def instantiate(hash_to_merge = {}, instance = active_record_class.new)
50
+ returning instance do
51
+ instantiate_parent_fixture(instance)
52
+ call_attribute_body(instance, hash_to_merge)
53
+ add_given_keys(instance, hash_to_merge)
54
+ end
55
+ end
56
+
57
+ def validate!
58
+ new_instance = instantiate
59
+
60
+ unless new_instance.valid?
61
+ errors = "new_#{fixture_name} is not valid! - Errors: "
62
+ errors << new_instance.errors.map { |key, value| "[#{key}: #{value}]"}.join(", ")
63
+ raise InvalidInstance, errors
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ class InvalidKeyError < StandardError; end
70
+
71
+ def check_valid_keys(options_given, valid_keys)
72
+ options_given.each do |key, _|
73
+ unless valid_keys.include?(key)
74
+ raise InvalidKeyError, "#{key.inspect} is not a valid option to attributes_for. Valid keys are: #{valid_keys.inspect}"
75
+ end
76
+ end
77
+ end
78
+
79
+ def instantiate_parent_fixture(instance)
80
+ derived_fixture.instantiate({}, instance) if derived_fixture?
81
+ end
82
+
83
+ def call_attribute_body(instance, hash_to_merge)
84
+ if @attributes_proc.arity == 2
85
+ @attributes_proc.call(instance, hash_to_merge)
86
+ else
87
+ @attributes_proc.call(instance)
88
+ end
89
+ end
90
+
91
+ def add_given_keys(instance, hash_to_merge)
92
+ hash_to_merge.each do |key, value|
93
+ instance.send("#{key}=", value)
94
+ end
95
+ end
96
+
97
+ def find_derived_fixture
98
+ self.class.find_by_fixture_name(from)
99
+ end
100
+
101
+ def derived_fixture
102
+ @derived_fixture ||= find_derived_fixture
103
+ end
104
+
105
+ def derived_fixture?
106
+ derived_fixture ? true : false
107
+ end
108
+
109
+ def constantize(symbol)
110
+ symbol.to_s.camelize.constantize
111
+ end
112
+
113
+ def find_active_record_class
114
+ if @class
115
+ @class
116
+ else
117
+ begin
118
+ constantize(fixture_name)
119
+ rescue NameError => e
120
+ if derived_fixture?
121
+ derived_fixture.active_record_class
122
+ else
123
+ raise e
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end