Permalink
Browse files

first commit

  • Loading branch information...
0 parents commit db007127c6ac8b0ebb31839d122934aeb0e111d2 @rdy committed May 5, 2009
Showing with 248 additions and 0 deletions.
  1. +20 −0 MIT-LICENSE
  2. +13 −0 README
  3. +23 −0 Rakefile
  4. +1 −0 init.rb
  5. +1 −0 install.rb
  6. +174 −0 lib/fixture_builder.rb
  7. +4 −0 tasks/fixture_builder_tasks.rake
  8. +8 −0 test/fixture_builder_test.rb
  9. +3 −0 test/test_helper.rb
  10. +1 −0 uninstall.rb
@@ -0,0 +1,20 @@
+Copyright (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.
@@ -0,0 +1,13 @@
+FixtureBuilder
+==============
+
+Introduction goes here.
+
+
+Example
+=======
+
+Example goes here.
+
+
+Copyright (c) 2009 [name of plugin creator], released under the MIT license
@@ -0,0 +1,23 @@
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the fixture_builder plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+desc 'Generate documentation for the fixture_builder plugin.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'FixtureBuilder'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
@@ -0,0 +1 @@
+# Include hook code here
@@ -0,0 +1 @@
+# Install hook code here
@@ -0,0 +1,174 @@
+require 'md5'
+require 'fileutils'
+module FixtureBuilder
+ class << self
+ def configuration
+ @configuration ||= FixtureBuilder::Configuration.new
+ end
+
+ def configure
+ yield configuration
+ end
+ end
+
+ class Configuration
+ attr_accessor :select_sql, :delete_sql, :skip_tables, :files_to_check, :record_name_fields, :fixture_builder_file
+
+ def initialize
+ @custom_names = {}
+ @file_hashes = file_hashes
+ end
+
+ def select_sql
+ @select_sql ||= "SELECT * FROM `%s`"
+ end
+
+ def delete_sql
+ @delete_sql ||= "DELETE FROM `%s`"
+ end
+
+ def skip_tables
+ @skip_table ||= %w{ schema_migrations }
+ end
+
+ def files_to_check
+ @files_to_check ||= %w{ db/schema.rb spec/spec_helpers/girl.rb }
+ 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 factory
+ return unless rebuild_fixtures?
+ say "Building fixtures"
+ delete_tables
+ surface_errors { yield }
+ FileUtils.rm_rf(Rails.root.join(spec_or_test_dir, 'fixtures', '*.yml'))
+ dump_empty_fixtures_for_all_tables
+ dump_tables
+ write_config
+ end
+
+ private
+
+ def say(*messages)
+ puts messages.map { |message| "=> #{message}" }
+ 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 delete_tables
+ tables.each { |t| ActiveRecord::Base.connection.delete(delete_sql % t) }
+ end
+
+ def tables
+ ActiveRecord::Base.connection.tables - skip_tables
+ end
+
+ def name(custom_name, model_object)
+ key = [model_object.class.name, model_object.id]
+ @custom_names[key] = custom_name
+ model_object
+ end
+
+ def names_from_ivars!
+ instance_values.each do |var, value|
+ name(var, value) if value.is_a? ActiveRecord::Base
+ end
+ end
+
+ def record_name(record_hash)
+ key = [@table_name.classify, record_hash['id'].to_i]
+ @record_names << (name = @custom_names[key] || inferred_record_name(record_hash) )
+ name
+ end
+
+ def inferred_record_name(record_hash)
+ record_name_fields.each do |try|
+ if name = record_hash[try]
+ inferred_name = name.underscore.gsub(/\W/, ' ').squeeze(' ').tr(' ', '_')
+ count = @record_names.select { |name| name.starts_with?(inferred_name) }.size # CHANGED == to starts_with?
+ return count.zero? ? inferred_name : "#{inferred_name}_#{count}"
+ end
+ end
+
+ "#{@table_name}_#{@row_index.succ!}"
+ end
+
+ def dump_empty_fixtures_for_all_tables
+ tables.each do |@table_name|
+ write_fixture_file({})
+ end
+ end
+
+ def dump_tables
+ fixtures = tables.inject([]) do |files, @table_name|
+ rows = ActiveRecord::Base.connection.select_all(select_sql % @table_name)
+ next files if rows.empty?
+
+ @row_index = '000'
+ @record_names = []
+ fixture_data = rows.inject({}) do |hash, record|
+ hash.merge(record_name(record) => record)
+ end
+
+ write_fixture_file fixture_data
+
+ files + [File.basename(fixture_file)]
+ end
+ say "Built #{fixtures.to_sentence}"
+ end
+
+ def write_fixture_file(fixture_data)
+ File.open(fixture_file, 'w') do |file|
+ file.write fixture_data.to_yaml
+ end
+ end
+
+ def fixture_file
+ fixtures_dir("#{@table_name}.yml")
+ end
+
+ def fixtures_dir(path)
+ File.join(RAILS_ROOT, spec_or_test_dir, 'fixtures', path)
+ end
+
+ 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] = MD5.md5(File.read(File.join(RAILS_ROOT, filename))).to_s
+ hash
+ end
+ end
+
+ def read_config
+ return {} unless File.exist?(fixture_builder_file)
+ YAML.load_file(fixture_builder_file)
+ end
+
+ def write_config
+ File.open(fixture_builder_file, 'w') {|f| f.write(YAML.dump(@file_hashes))}
+ end
+
+ def rebuild_fixtures?
+ @file_hashes != read_config
+ end
+ end
+end
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :fixture_builder do
+# # Task goes here
+# end
@@ -0,0 +1,8 @@
+require 'test_helper'
+
+class FixtureBuilderTest < ActiveSupport::TestCase
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'active_support'
+require 'active_support/test_case'
@@ -0,0 +1 @@
+# Uninstall hook code here

0 comments on commit db00712

Please sign in to comment.