fixture_builder-0.3.6/0000755000004100000410000000000012224704653014751 5ustar www-datawww-datafixture_builder-0.3.6/MIT-LICENSE0000644000004100000410000000205412224704653016406 0ustar www-datawww-dataCopyright (c) 2009 [name of plugin creator] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fixture_builder-0.3.6/.travis.yml0000644000004100000410000000005012224704653017055 0ustar www-datawww-datalanguage: ruby rvm: - 1.8.7 - 1.9.2 fixture_builder-0.3.6/test/0000755000004100000410000000000012224704653015730 5ustar www-datawww-datafixture_builder-0.3.6/test/legacy_fixture_mode_fixture_generation_test.rb0000644000004100000410000000332412224704653027315 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) class LegacyFixtureModeFixtureGenerationTest < Test::Unit::TestCase def setup create_and_blow_away_old_db force_fixture_generation FixtureBuilder.configure do |fbuilder| fbuilder.legacy_fixtures = Dir[test_path("legacy_fixtures/*.yml"), test_path("other_legacy_fixture_set/*.yml")] fbuilder.factory do MagicalCreature.create(:name => "frank", :species => "unicorn") MagicalCreature.create(:name => "loch ness monster", :species => "sea creature", :deleted => true) end end @@magical_creatures = YAML.load(File.open(test_path("fixtures/magical_creatures.yml"))) end def teardown FixtureBuilder.send(:remove_instance_variable, :@configuration) end def test_legacy_fixtures_created alice = MagicalCreature.find_by_name("alice") assert_equal "alice", alice.name assert_equal "mermaid", alice.species end def test_invalid_legacy_fixtures_created bigfoot = MagicalCreature.find(5) assert_equal "bigfoot", bigfoot.name assert_equal 5, @@magical_creatures['bigfoot']['id'] assert_equal "bigfoot", @@magical_creatures['bigfoot']['name'] assert_nil @@magical_creatures['bigfoot']['species'] end def test_new_fixtures_are_created assert_equal "frank", @@magical_creatures['frank']['name'] assert_equal "unicorn", @@magical_creatures['frank']['species'] assert_equal "loch ness monster", @@magical_creatures['loch_ness_monster']['name'] end def test_legacy_fixtures_retain_fixture_name assert_equal "alice", @@magical_creatures['alice_the_mermaid']['name'] assert_equal "mermaid", @@magical_creatures['alice_the_mermaid']['species'] end endfixture_builder-0.3.6/test/legacy_fixtures/0000755000004100000410000000000012224704653021125 5ustar www-datawww-datafixture_builder-0.3.6/test/legacy_fixtures/magical_creatures.yml0000644000004100000410000000021612224704653025321 0ustar www-datawww-databigfoot: name: bigfoot id: 5 alice_the_mermaid: name: alice species: mermaid id: 300 xou_the_dragon: name: xou species: dragonfixture_builder-0.3.6/test/namer_test.rb0000644000004100000410000000357112224704653020424 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) class Model def self.table_name 'models' end end class AnotherModel def self.table_name 'another_models' end end class MockFixture def self.[](*args) '1' end def self.model_class Model end end class NamerTest < Test::Unit::TestCase def setup configuration = FixtureBuilder::Configuration.new @namer = FixtureBuilder::Namer.new(configuration) end def test_name_with hash = { 'id' => 1, 'email' => 'bob@example.com' } @namer.name_model_with Model do |record_hash, index| [record_hash['email'].split('@').first, index].join('_') end assert_equal 'bob_001', @namer.record_name(hash, Model.table_name, '000') end def test_record_name_without_name_with_or_custom_name hash = { 'id' => 1, 'email' => 'bob@example.com' } assert_equal 'models_001', @namer.record_name(hash, Model.table_name, '000') end def test_record_name_with_inferred_record_name hash = { 'id' => 1, 'title' => 'foo', 'email' => 'bob@example.com' } assert_equal 'foo', @namer.record_name(hash, Model.table_name, '000') end def test_name_not_unique_across_tables hash = { 'id' => 1, 'title' => 'foo' } hash_with_same_title = { 'id' => 2, 'title' => 'foo' } assert_equal 'foo', @namer.record_name(hash, Model.table_name, '000') assert_equal 'foo', @namer.record_name(hash, AnotherModel.table_name, '000') assert_equal 'foo_1', @namer.record_name(hash_with_same_title, Model.table_name, '000') end def test_populate_custom_names_for_rails_30_and_earlier mock_fixtures = { 'foo' => MockFixture } @namer.populate_custom_names(mock_fixtures) assert_equal 'foo', @namer.record_name(MockFixture, Model.table_name, '1') end end fixture_builder-0.3.6/test/legacy_fixture_mode_test.rb0000644000004100000410000000237412224704653023340 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) class LegacyFixtureModeTest < Test::Unit::TestCase def setup create_and_blow_away_old_db force_fixture_generation end def teardown FixtureBuilder.send(:remove_instance_variable, :@configuration) end def test_load_legacy_fixtures FixtureBuilder.configure do |fbuilder| fbuilder.legacy_fixtures = Dir[test_path("legacy_fixtures/*.yml"), test_path("other_legacy_fixture_set/*.yml")] fbuilder.factory do end end assert_equal 3, MagicalCreature.all.size end def test_generate_new_fixtures_without_legacy FixtureBuilder.configure do |fbuilder| fbuilder.files_to_check += Dir[test_path("*.rb")] fbuilder.factory do MagicalCreature.create :name => "Melinda", :species => "Philanthropist" end end assert_equal 1, MagicalCreature.all.size end def test_new_and_old_fixtures FixtureBuilder.configure do |fbuilder| fbuilder.legacy_fixtures = Dir[test_path("legacy_fixtures/*.yml"), test_path("other_legacy_fixture_set/*.yml")] fbuilder.factory do MagicalCreature.create :name => "Barry", :species => "Party Guy" end end assert_equal 4, MagicalCreature.all.size end end fixture_builder-0.3.6/test/test_helper.rb0000644000004100000410000000231012224704653020567 0ustar www-datawww-datarequire 'rubygems' require 'bundler/setup' require 'test/unit' class Rails def self.root Pathname.new(File.join(File.dirname(__FILE__), '..')) end end def test_path(glob) File.join(Rails.root, 'test', glob) end require 'active_support/concern' require 'active_record' require 'active_record/test_case' require 'active_record/fixtures' def create_fixtures(*table_names, &block) Fixtures.create_fixtures(ActiveSupport::TestCase.fixture_path, table_names, {}, &block) end require 'sqlite3' require 'fixture_builder' class MagicalCreature < ActiveRecord::Base validates_presence_of :name, :species default_scope :conditions => { :deleted => false } end def create_and_blow_away_old_db ActiveRecord::Base.configurations['test'] = { 'adapter' => 'sqlite3', 'database' => 'test.db' } ActiveRecord::Base.establish_connection(:test) ActiveRecord::Base.connection.create_table(:magical_creatures, :force => true) do |t| t.column :name, :string t.column :species, :string t.column :deleted, :boolean, :default => false, :null => false end end def force_fixture_generation begin FileUtils.rm(File.expand_path("../../tmp/fixture_builder.yml", __FILE__)) rescue end endfixture_builder-0.3.6/test/fixtures/0000755000004100000410000000000012224704653017601 5ustar www-datawww-datafixture_builder-0.3.6/test/fixtures/.gitkeep0000644000004100000410000000000012224704653021220 0ustar www-datawww-datafixture_builder-0.3.6/test/fixture_builder_test.rb0000644000004100000410000000302112224704653022504 0ustar www-datawww-datarequire File.expand_path(File.join(File.dirname(__FILE__), 'test_helper')) class Model def self.table_name 'models' end end class FixtureBuilderTest < Test::Unit::TestCase def teardown FixtureBuilder.instance_variable_set(:'@configuration', nil) end def test_name_with hash = { 'id' => 1, 'email' => 'bob@example.com' } FixtureBuilder.configure do |config| config.name_model_with Model do |record_hash, index| [record_hash['email'].split('@').first, index].join('_') end end assert_equal 'bob_001', FixtureBuilder.configuration.send(:record_name, hash, Model.table_name, '000') end def test_ivar_naming create_and_blow_away_old_db force_fixture_generation FixtureBuilder.configure do |fbuilder| fbuilder.files_to_check += Dir[test_path("*.rb")] fbuilder.factory do @king_of_gnomes = MagicalCreature.create(:name => 'robert', :species => 'gnome') end end generated_fixture = YAML.load(File.open(test_path("fixtures/magical_creatures.yml"))) assert_equal 'king_of_gnomes', generated_fixture.keys.first end def test_configure FixtureBuilder.configure do |config| assert config.is_a?(FixtureBuilder::Configuration) @called = true end assert @called end def test_spec_or_test_dir assert_equal 'test', FixtureBuilder.configuration.send(:spec_or_test_dir) end def test_fixtures_dir assert_match /test\/fixtures$/, FixtureBuilder.configuration.send(:fixtures_dir).to_s end end fixture_builder-0.3.6/.pairs0000644000004100000410000000023112224704653016064 0ustar www-datawww-datapairs: rd: Ryan Dy js: Josh Susser; jsusser tb: Thomas Bukowski; tbukowski dc: Dennis Collinson email: prefix: pair domain: pivotallabs.com fixture_builder-0.3.6/Rakefile0000644000004100000410000000036212224704653016417 0ustar www-datawww-datarequire 'bundler' include Rake::DSL if defined?(Rake::DSL) Bundler::GemHelper.install_tasks require 'rake/testtask' Rake::TestTask.new(:test) do |t| t.test_files = FileList['test/*_test.rb'] t.verbose = false end task :default => :test fixture_builder-0.3.6/README.markdown0000644000004100000410000001033112224704653017450 0ustar www-datawww-dataFixtureBuilder ============== [![Build Status](https://secure.travis-ci.org/rdy/fixture_builder.png)](http://travis-ci.org/rdy/fixture_builder) Based on the code from fixture_scenarios, by Chris Wanstrath. Allows you to build file fixtures from an object mother factory. Installing ========== 1. Install as a plugin or gem: `gem install fixture_builder` 1. Create a file which configures and declares your fixtures (see below for example) 1. Require the above file in your `spec_helper.rb` or `test_helper.rb` Example ======= When using an object mother such as factory_girl it can be setup like the following: # I usually put this file in spec/support/fixture_builder.rb FixtureBuilder.configure do |fbuilder| # rebuild fixtures automatically when these files change: fbuilder.files_to_check += Dir["spec/factories/*.rb", "spec/support/fixture_builder.rb"] # now declare objects fbuilder.factory do david = Factory(:user, :unique_name => "david") ipod = Factory(:product, :name => "iPod") Factory(:purchase, :user => david, :product => ipod) end end The block passed to the factory method initiates the creation of the fixture files. Before yielding to the block, FixtureBuilder cleans out the test database completely. When the block finishes, it dumps the state of the database into fixtures, like this: # users.yml david: created_at: 2010-09-18 17:21:23.926511 Z unique_name: david id: 1 # products.yml i_pod: name: iPod id: 1 # purchases.yml purchase_001: product_id: 1 user_id: 1 FixtureBuilder guesses about how to name fixtures based on a prioritized list of attribute names. You can also hint at a name or manually name an object. Both of the following lines would work to rename `purchase_001` to `davids_ipod`: fbuilder.name(:davids_ipod, Factory(:purchase, :user => david, :product => ipod)) @davids_ipod = Factory(:purchase, :user => david, :product => ipod) Another way to name fixtures is to use the name_model_with. To use it you create a block that returns how you want a certain model name based on the record field. fbuilder.name_model_with(User) do |record| [record['first_name'], record['last_name']].join('_') end For all User fixture {first_name: 'foo', last_name: 'bar'} it would generate `foo_bar` as the fixture name. There are also additional configuration options that can be changed to override the defaults: * files_to_check: array of filenames that when changed cause fixtures to be rebuilt * fixture_builder_file: the pathname of the file used to store file changes. * record_name_fields: array of field names to use as a fixture's name prefix, it will use the first matching field it finds * skip_tables: array of table names to skip building fixtures * select_sql: sql string to use for select * delete_sql: sql string to use for deletes By default these are set as: * files_to_check: %w{ db/schema.rb } * fixture_builder_file: RAILS_ROOT/tmp/fixture_builder.yml * record_name_fields: %w{ schema_migrations } * skip_tables: %w{ schema_migrations } * select_sql: SELECT * FROM %s * delete_sql: DELETE FROM %s Sequence Collisions =================== One problem with generating your fixtures is that sequences can collide. When the fixtures are generated only as needed, sometimes the process that generates the fixtures will be different than the process that runs the tests. This results in collisions when you still use factories in your tests. Here's a solution for FactoryGirl which resets sequences numbers to 1000 (to avoid conflicts with fixture data which should e sequenced < 1000) before the tests run: FixtureBuilder.configure do |fbuilder| ... end # Have factory girl generate non-colliding sequences starting at 1000 for data created after the fixtures # Factory Girl <2 yields name & seq # Factory Girl >2 yeilds only seq FactoryGirl.sequences.each do |seq| # Factory Girl 4 uses an Enumerator Adapter, otherwise simply set a Fixnum seq.instance_variable_set(:@value, FactoryGirl::Sequence::EnumeratorAdapter.new(2000)) end Copyright (c) 2009 Ryan Dy & David Stevenson, released under the MIT license fixture_builder-0.3.6/tmp/0000755000004100000410000000000012224704653015551 5ustar www-datawww-datafixture_builder-0.3.6/tmp/.gitkeep0000644000004100000410000000000012224704653017170 0ustar www-datawww-datafixture_builder-0.3.6/metadata.yml0000644000004100000410000001046712224704653017264 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: fixture_builder version: !ruby/object:Gem::Version version: 0.3.6 prerelease: platform: ruby authors: - Ryan Dy - David Stevenson autorequire: bindir: bin cert_chain: [] date: 2013-06-17 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: activerecord requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' - !ruby/object:Gem::Dependency name: activesupport requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' - !ruby/object:Gem::Dependency name: rake requirement: !ruby/object:Gem::Requirement none: false requirements: - - '=' - !ruby/object:Gem::Version version: 0.8.7 type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - '=' - !ruby/object:Gem::Version version: 0.8.7 - !ruby/object:Gem::Dependency name: rails requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '2' - !ruby/object:Gem::Dependency name: test-unit requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' - !ruby/object:Gem::Dependency name: sqlite3 requirement: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' description: FixtureBuilder allows testers to use their existing factories, like FactoryGirl, to generate high performance fixtures that can be shared across all your tests email: mail@ryandy.com executables: [] extensions: [] extra_rdoc_files: - README.markdown files: - .gitignore - .pairs - .rvmrc - .travis.yml - Gemfile - MIT-LICENSE - README.markdown - Rakefile - fixture_builder.gemspec - lib/fixture_builder.rb - lib/fixture_builder/builder.rb - lib/fixture_builder/configuration.rb - lib/fixture_builder/delegations.rb - lib/fixture_builder/namer.rb - lib/fixture_builder/version.rb - lib/tasks/fixture_builder.rake - test/fixture_builder_test.rb - test/fixtures/.gitkeep - test/legacy_fixture_mode_fixture_generation_test.rb - test/legacy_fixture_mode_test.rb - test/legacy_fixtures/magical_creatures.yml - test/namer_test.rb - test/test_helper.rb - tmp/.gitkeep homepage: http://github.com/rdy/fixture_builder licenses: - MIT post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' segments: - 0 hash: -260464205711861876 required_rubygems_version: !ruby/object:Gem::Requirement none: false requirements: - - ! '>=' - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: fixture_builder rubygems_version: 1.8.24 signing_key: specification_version: 3 summary: Build YAML fixtures using object factories test_files: - test/fixture_builder_test.rb - test/fixtures/.gitkeep - test/legacy_fixture_mode_fixture_generation_test.rb - test/legacy_fixture_mode_test.rb - test/legacy_fixtures/magical_creatures.yml - test/namer_test.rb - test/test_helper.rb fixture_builder-0.3.6/fixture_builder.gemspec0000644000004100000410000000237612224704653021522 0ustar www-datawww-data# -*- encoding: utf-8 -*- $:.push File.expand_path('../lib', __FILE__) require 'fixture_builder/version' Gem::Specification.new do |s| s.name = %q{fixture_builder} s.version = FixtureBuilder::VERSION s.platform = Gem::Platform::RUBY s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version= s.authors = ['Ryan Dy', 'David Stevenson'] s.description = %q{FixtureBuilder allows testers to use their existing factories, like FactoryGirl, to generate high performance fixtures that can be shared across all your tests} s.email = %q{mail@ryandy.com} s.licenses = ['MIT'] s.extra_rdoc_files = [ 'README.markdown' ] s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.require_paths = ['lib'] s.homepage = %q{http://github.com/rdy/fixture_builder} s.rubyforge_project = %q{fixture_builder} s.summary = %q{Build YAML fixtures using object factories} s.add_dependency %q{activerecord}, '>= 2' s.add_dependency %q{activesupport}, '>= 2' s.add_development_dependency %q{rake}, '0.8.7' s.add_development_dependency %q{rails}, '>= 2' s.add_development_dependency %q{test-unit} s.add_development_dependency %q{sqlite3} end fixture_builder-0.3.6/Gemfile0000644000004100000410000000004612224704653016244 0ustar www-datawww-datasource 'http://rubygems.org' gemspec fixture_builder-0.3.6/.gitignore0000644000004100000410000000014212224704653016736 0ustar www-datawww-datapkg/ .pairs .idea/* *.db tmp/fixture_builder.yml test/fixtures/magical_creatures.yml Gemfile.lock fixture_builder-0.3.6/lib/0000755000004100000410000000000012224704653015517 5ustar www-datawww-datafixture_builder-0.3.6/lib/tasks/0000755000004100000410000000000012224704653016644 5ustar www-datawww-datafixture_builder-0.3.6/lib/tasks/fixture_builder.rake0000644000004100000410000000125312224704653022705 0ustar www-datawww-datanamespace :spec do namespace :fixture_builder do desc "Deletes the generated fixtures in spec/fixtures" task :clean do FileUtils.rm_f("tmp/fixture_builder.yml") FileUtils.rm_f(Dir.glob('spec/fixtures/*.yml')) puts "Automatically generated fixtures removed" end desc "Build the generated fixtures to spec/fixtures if dirty" task :build => :environment do ActiveRecord::Base.establish_connection('test') Dir.glob(File.join(Rails.root, '{spec,test}', '**', 'fixture_builder.rb')).each{|file| require(file)} end desc "Clean and rebuild the generated fixtures to spec/fixtures" task :rebuild => [:clean, :build] end end fixture_builder-0.3.6/lib/fixture_builder/0000755000004100000410000000000012224704653020713 5ustar www-datawww-datafixture_builder-0.3.6/lib/fixture_builder/version.rb0000644000004100000410000000005612224704653022726 0ustar www-datawww-datamodule FixtureBuilder VERSION = '0.3.6' end fixture_builder-0.3.6/lib/fixture_builder/builder.rb0000644000004100000410000000746012224704653022675 0ustar www-datawww-datamodule FixtureBuilder class Builder include Delegations::Namer include Delegations::Configuration def initialize(configuration, namer, builder_block) @configuration = configuration @namer = namer @builder_block = builder_block end def generate! say "Building fixtures" clean_out_old_data create_fixture_objects names_from_ivars! write_data_to_files after_build.call if after_build end protected def create_fixture_objects load_legacy_fixtures if legacy_fixtures.present? surface_errors { instance_eval &@builder_block } end def load_legacy_fixtures legacy_fixtures.each do |fixture_file| # Rails 3.0 and 3.1+ support fixtures_class = defined?(ActiveRecord::Fixtures) ? ActiveRecord::Fixtures : ::Fixtures fixtures = fixtures_class.create_fixtures(File.dirname(fixture_file), File.basename(fixture_file, '.*')) populate_custom_names(fixtures) end end def surface_errors yield rescue Object => error puts say "There was an error building fixtures", error.inspect puts puts error.backtrace puts exit! end def names_from_ivars! instance_values.each do |var, value| name(var, value) if value.is_a? ActiveRecord::Base end end def write_data_to_files delete_yml_files dump_empty_fixtures_for_all_tables dump_tables end def clean_out_old_data delete_tables delete_yml_files end def delete_tables ActiveRecord::Base.connection.disable_referential_integrity do tables.each { |t| ActiveRecord::Base.connection.delete(delete_sql % ActiveRecord::Base.connection.quote_table_name(t)) } end end def delete_yml_files FileUtils.rm(Dir.glob(fixtures_dir('*.yml'))) rescue nil end def say(*messages) puts messages.map { |message| "=> #{message}" } end def dump_empty_fixtures_for_all_tables tables.each do |table_name| write_fixture_file({}, table_name) end end def dump_tables default_date_format = Date::DATE_FORMATS[:default] Date::DATE_FORMATS[:default] = Date::DATE_FORMATS[:db] begin fixtures = tables.inject([]) do |files, table_name| table_klass = table_name.classify.constantize rescue nil if table_klass && table_klass < ActiveRecord::Base rows = table_klass.unscoped do table_klass.all.collect do |obj| attrs = obj.attributes attrs.inject({}) do |hash, (attr_name, value)| if table_klass.serialized_attributes.has_key? attr_name hash[attr_name] = table_klass.serialized_attributes[attr_name].dump(value) else hash[attr_name] = value end hash end end end else rows = ActiveRecord::Base.connection.select_all(select_sql % ActiveRecord::Base.connection.quote_table_name(table_name)) end next files if rows.empty? row_index = '000' fixture_data = rows.inject({}) do |hash, record| hash.merge(record_name(record, table_name, row_index) => record) end write_fixture_file fixture_data, table_name files + [File.basename(fixture_file(table_name))] end ensure Date::DATE_FORMATS[:default] = default_date_format end say "Built #{fixtures.to_sentence}" end def write_fixture_file(fixture_data, table_name) File.open(fixture_file(table_name), 'w') do |file| file.write fixture_data.to_yaml end end def fixture_file(table_name) fixtures_dir("#{table_name}.yml") end end end fixture_builder-0.3.6/lib/fixture_builder/configuration.rb0000644000004100000410000000536312224704653024116 0ustar www-datawww-datarequire 'active_support/core_ext' require 'active_support/core_ext/string' require 'digest/md5' require 'fileutils' module FixtureBuilder class Configuration include Delegations::Namer ACCESSIBLE_ATTRIBUTES = [:select_sql, :delete_sql, :skip_tables, :files_to_check, :record_name_fields, :fixture_builder_file, :after_build, :legacy_fixtures, :model_name_procs] attr_accessor(*ACCESSIBLE_ATTRIBUTES) SCHEMA_FILES = ['db/schema.rb', 'db/development_structure.sql', 'db/test_structure.sql', 'db/production_structure.sql'] def initialize(opts={}) @namer = Namer.new(self) @file_hashes = file_hashes end def include(*args) class_eval do args.each do |arg| include arg end end end def factory(&block) self.files_to_check += @legacy_fixtures.to_a return unless rebuild_fixtures? @builder = Builder.new(self, @namer, block).generate! write_config end def select_sql @select_sql ||= "SELECT * FROM %s" end def delete_sql @delete_sql ||= "DELETE FROM %s" end def skip_tables @skip_tables ||= %w{ schema_migrations } end def files_to_check @files_to_check ||= schema_definition_files end def schema_definition_files Dir['db/*'].inject([]) do |result, file| result << file if SCHEMA_FILES.include?(file) result end end def files_to_check=(files) @files_to_check = files @file_hashes = file_hashes @files_to_check end def record_name_fields @record_name_fields ||= %w{ unique_name display_name name title username login } end def fixture_builder_file @fixture_builder_file ||= ::Rails.root.join('tmp', 'fixture_builder.yml') end def name_model_with(model_class, &block) @namer.name_model_with(model_class, &block) end def tables ActiveRecord::Base.connection.tables - skip_tables end def fixtures_dir(path = '') File.expand_path(File.join(::Rails.root, spec_or_test_dir, 'fixtures', path)) end private def spec_or_test_dir File.exists?(File.join(::Rails.root, 'spec')) ? 'spec' : 'test' end def file_hashes files_to_check.inject({}) do |hash, filename| hash[filename] = Digest::MD5.hexdigest(File.read(filename)) hash end end def read_config return {} unless File.exist?(fixture_builder_file) YAML.load_file(fixture_builder_file) end def write_config FileUtils.mkdir_p(File.dirname(fixture_builder_file)) File.open(fixture_builder_file, 'w') { |f| f.write(YAML.dump(@file_hashes)) } end def rebuild_fixtures? @file_hashes != read_config end end end fixture_builder-0.3.6/lib/fixture_builder/namer.rb0000644000004100000410000000476512224704653022356 0ustar www-datawww-datamodule FixtureBuilder class Namer include Delegations::Configuration def initialize(configuration) @configuration = configuration @custom_names = {} @model_name_procs = {} @record_names = {} end def name_model_with(model_class, &block) @model_name_procs[model_class.table_name] = block end def name(custom_name, *model_objects) raise "Cannot name an object blank" unless custom_name.present? model_objects.each do |model_object| raise "Cannot name a blank object" unless model_object.present? key = [model_object.class.table_name, model_object.id] raise "Cannot set name for #{key.inspect} object twice" if @custom_names[key] @custom_names[key] = custom_name model_object end end def populate_custom_names(created_fixtures) # Rails 3.1+, create_fixtures returns an array of Fixtures objects if not created_fixtures.first.is_a? Array # merge all fixtures hashes created_fixtures = created_fixtures.inject({}) { |hash, fixtures| hash.merge(fixtures.fixtures) } end # Rails 3.0 and earlier, create_fixtures returns an array of tuples created_fixtures.each do |fixture| name = fixture[0] id = fixture[1]['id'].to_i table_name = fixture[1].model_class.table_name key = [table_name, id] @custom_names[key] = name end end def record_name(record_hash, table_name, row_index) key = [table_name, record_hash['id'].to_i] name = case when name_proc = @model_name_procs[table_name] name_proc.call(record_hash, row_index.succ!) when custom = @custom_names[key] custom else inferred_record_name(record_hash, table_name, row_index) end @record_names[table_name] ||= [] @record_names[table_name] << name name.to_s end protected def inferred_record_name(record_hash, table_name, row_index) record_name_fields.each do |try| if name = record_hash[try] inferred_name = name.underscore.gsub(/\W/, ' ').squeeze(' ').tr(' ', '_') count = 0 if @record_names[table_name] count = @record_names[table_name].select {|name| name.to_s.starts_with?(inferred_name) }.size end return count.zero? ? inferred_name : "#{inferred_name}_#{count}" end end [table_name, row_index.succ!].join('_') end end endfixture_builder-0.3.6/lib/fixture_builder/delegations.rb0000644000004100000410000000112512224704653023535 0ustar www-datawww-datarequire 'active_support/core_ext/module/delegation' module FixtureBuilder module Delegations module Configuration def self.included(base) methods_to_delegate = [:fixtures_dir, :tables, :legacy_fixtures].concat(::FixtureBuilder::Configuration::ACCESSIBLE_ATTRIBUTES).flatten methods_to_delegate.each do |meth| base.delegate(meth, :to => :@configuration) end end end module Namer def self.included(base) base.delegate :record_name, :populate_custom_names, :name, :name_model_with, :to => :@namer end end end endfixture_builder-0.3.6/lib/fixture_builder.rb0000644000004100000410000000102312224704653021234 0ustar www-datawww-datarequire 'fixture_builder/delegations' require 'fixture_builder/configuration' require 'fixture_builder/namer' require 'fixture_builder/builder' module FixtureBuilder class << self def configuration(opts = {}) @configuration ||= FixtureBuilder::Configuration.new(opts) end def configure(opts = {}) yield configuration(opts) end end begin class Railtie < ::Rails::Railtie rake_tasks do load "tasks/fixture_builder.rake" end end rescue LoadError, NameError end end fixture_builder-0.3.6/.rvmrc0000644000004100000410000000004312224704653016100 0ustar www-datawww-datarvm 1.9.3@fixture_builder --create