fixture_replacement 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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