Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

first commit

  • Loading branch information...
commit db007127c6ac8b0ebb31839d122934aeb0e111d2 0 parents
Ryan Dy authored May 04, 2009
20  MIT-LICENSE
... ...
@@ -0,0 +1,20 @@
  1
+Copyright (c) 2009 [name of plugin creator]
  2
+
  3
+Permission is hereby granted, free of charge, to any person obtaining
  4
+a copy of this software and associated documentation files (the
  5
+"Software"), to deal in the Software without restriction, including
  6
+without limitation the rights to use, copy, modify, merge, publish,
  7
+distribute, sublicense, and/or sell copies of the Software, and to
  8
+permit persons to whom the Software is furnished to do so, subject to
  9
+the following conditions:
  10
+
  11
+The above copyright notice and this permission notice shall be
  12
+included in all copies or substantial portions of the Software.
  13
+
  14
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13  README
... ...
@@ -0,0 +1,13 @@
  1
+FixtureBuilder
  2
+==============
  3
+
  4
+Introduction goes here.
  5
+
  6
+
  7
+Example
  8
+=======
  9
+
  10
+Example goes here.
  11
+
  12
+
  13
+Copyright (c) 2009 [name of plugin creator], released under the MIT license
23  Rakefile
... ...
@@ -0,0 +1,23 @@
  1
+require 'rake'
  2
+require 'rake/testtask'
  3
+require 'rake/rdoctask'
  4
+
  5
+desc 'Default: run unit tests.'
  6
+task :default => :test
  7
+
  8
+desc 'Test the fixture_builder plugin.'
  9
+Rake::TestTask.new(:test) do |t|
  10
+  t.libs << 'lib'
  11
+  t.libs << 'test'
  12
+  t.pattern = 'test/**/*_test.rb'
  13
+  t.verbose = true
  14
+end
  15
+
  16
+desc 'Generate documentation for the fixture_builder plugin.'
  17
+Rake::RDocTask.new(:rdoc) do |rdoc|
  18
+  rdoc.rdoc_dir = 'rdoc'
  19
+  rdoc.title    = 'FixtureBuilder'
  20
+  rdoc.options << '--line-numbers' << '--inline-source'
  21
+  rdoc.rdoc_files.include('README')
  22
+  rdoc.rdoc_files.include('lib/**/*.rb')
  23
+end
1  init.rb
... ...
@@ -0,0 +1 @@
  1
+# Include hook code here
1  install.rb
... ...
@@ -0,0 +1 @@
  1
+# Install hook code here
174  lib/fixture_builder.rb
... ...
@@ -0,0 +1,174 @@
  1
+require 'md5'
  2
+require 'fileutils'
  3
+module FixtureBuilder
  4
+  class << self
  5
+    def configuration
  6
+      @configuration ||= FixtureBuilder::Configuration.new
  7
+    end
  8
+    
  9
+    def configure
  10
+      yield configuration
  11
+    end
  12
+  end
  13
+
  14
+  class Configuration
  15
+    attr_accessor :select_sql, :delete_sql, :skip_tables, :files_to_check, :record_name_fields, :fixture_builder_file
  16
+
  17
+    def initialize
  18
+      @custom_names = {}
  19
+      @file_hashes = file_hashes
  20
+    end
  21
+
  22
+    def select_sql
  23
+      @select_sql ||= "SELECT * FROM `%s`"
  24
+    end
  25
+
  26
+    def delete_sql
  27
+      @delete_sql ||= "DELETE FROM `%s`"
  28
+    end
  29
+
  30
+    def skip_tables
  31
+      @skip_table ||= %w{ schema_migrations }
  32
+    end
  33
+
  34
+    def files_to_check
  35
+      @files_to_check ||= %w{ db/schema.rb spec/spec_helpers/girl.rb }
  36
+    end
  37
+
  38
+    def record_name_fields
  39
+      @record_name_fields ||= %w{ unique_name display_name name title username login }
  40
+    end
  41
+
  42
+    def fixture_builder_file
  43
+      @fixture_builder_file ||= Rails.root.join('tmp', 'fixture_builder.yml')
  44
+    end
  45
+
  46
+    def factory
  47
+      return unless rebuild_fixtures?
  48
+      say "Building fixtures"
  49
+      delete_tables
  50
+      surface_errors { yield }
  51
+      FileUtils.rm_rf(Rails.root.join(spec_or_test_dir, 'fixtures', '*.yml'))
  52
+      dump_empty_fixtures_for_all_tables
  53
+      dump_tables
  54
+      write_config
  55
+    end
  56
+  
  57
+    private
  58
+  
  59
+    def say(*messages)
  60
+      puts messages.map { |message| "=> #{message}" }
  61
+    end
  62
+
  63
+    def surface_errors
  64
+      yield
  65
+    rescue Object => error
  66
+      puts
  67
+      say "There was an error building fixtures", error.inspect
  68
+      puts
  69
+      puts error.backtrace
  70
+      puts
  71
+      exit!
  72
+    end
  73
+
  74
+    def delete_tables
  75
+      tables.each { |t| ActiveRecord::Base.connection.delete(delete_sql % t)  }
  76
+    end
  77
+
  78
+    def tables
  79
+      ActiveRecord::Base.connection.tables - skip_tables
  80
+    end
  81
+
  82
+    def name(custom_name, model_object)
  83
+      key = [model_object.class.name, model_object.id]
  84
+      @custom_names[key] = custom_name
  85
+      model_object
  86
+    end
  87
+
  88
+    def names_from_ivars!
  89
+      instance_values.each do |var, value|
  90
+        name(var, value) if value.is_a? ActiveRecord::Base
  91
+      end
  92
+    end
  93
+
  94
+    def record_name(record_hash)
  95
+      key = [@table_name.classify, record_hash['id'].to_i]
  96
+      @record_names << (name = @custom_names[key] || inferred_record_name(record_hash) )
  97
+      name
  98
+    end
  99
+
  100
+    def inferred_record_name(record_hash)
  101
+      record_name_fields.each do |try|
  102
+        if name = record_hash[try]
  103
+          inferred_name = name.underscore.gsub(/\W/, ' ').squeeze(' ').tr(' ', '_')
  104
+          count = @record_names.select { |name| name.starts_with?(inferred_name) }.size   # CHANGED == to starts_with?
  105
+          return count.zero? ? inferred_name : "#{inferred_name}_#{count}"
  106
+        end
  107
+      end
  108
+
  109
+      "#{@table_name}_#{@row_index.succ!}"
  110
+    end
  111
+
  112
+    def dump_empty_fixtures_for_all_tables
  113
+      tables.each do |@table_name|
  114
+        write_fixture_file({})
  115
+      end
  116
+    end
  117
+
  118
+    def dump_tables
  119
+      fixtures = tables.inject([]) do |files, @table_name|
  120
+        rows = ActiveRecord::Base.connection.select_all(select_sql % @table_name)
  121
+        next files if rows.empty?
  122
+
  123
+        @row_index      = '000'
  124
+        @record_names = []
  125
+        fixture_data = rows.inject({}) do |hash, record|
  126
+          hash.merge(record_name(record) => record)
  127
+        end
  128
+
  129
+        write_fixture_file fixture_data
  130
+
  131
+        files + [File.basename(fixture_file)]
  132
+      end
  133
+      say "Built #{fixtures.to_sentence}"
  134
+    end
  135
+
  136
+    def write_fixture_file(fixture_data)
  137
+      File.open(fixture_file, 'w') do |file|
  138
+        file.write fixture_data.to_yaml
  139
+      end
  140
+    end
  141
+
  142
+    def fixture_file
  143
+      fixtures_dir("#{@table_name}.yml")
  144
+    end
  145
+
  146
+    def fixtures_dir(path)
  147
+      File.join(RAILS_ROOT, spec_or_test_dir, 'fixtures', path)
  148
+    end
  149
+
  150
+    def spec_or_test_dir
  151
+      File.exists?(File.join(RAILS_ROOT, 'spec')) ? 'spec' : 'test'
  152
+    end
  153
+
  154
+    def file_hashes
  155
+      files_to_check.inject({}) do |hash, filename|
  156
+        hash[filename] = MD5.md5(File.read(File.join(RAILS_ROOT, filename))).to_s
  157
+        hash
  158
+      end
  159
+    end
  160
+
  161
+    def read_config
  162
+      return {} unless File.exist?(fixture_builder_file)
  163
+      YAML.load_file(fixture_builder_file)
  164
+    end
  165
+
  166
+    def write_config
  167
+      File.open(fixture_builder_file, 'w') {|f| f.write(YAML.dump(@file_hashes))}
  168
+    end
  169
+
  170
+    def rebuild_fixtures?
  171
+      @file_hashes != read_config
  172
+    end
  173
+  end
  174
+end
4  tasks/fixture_builder_tasks.rake
... ...
@@ -0,0 +1,4 @@
  1
+# desc "Explaining what the task does"
  2
+# task :fixture_builder do
  3
+#   # Task goes here
  4
+# end
8  test/fixture_builder_test.rb
... ...
@@ -0,0 +1,8 @@
  1
+require 'test_helper'
  2
+
  3
+class FixtureBuilderTest < ActiveSupport::TestCase
  4
+  # Replace this with your real tests.
  5
+  test "the truth" do
  6
+    assert true
  7
+  end
  8
+end
3  test/test_helper.rb
... ...
@@ -0,0 +1,3 @@
  1
+require 'rubygems'
  2
+require 'active_support'
  3
+require 'active_support/test_case'
1  uninstall.rb
... ...
@@ -0,0 +1 @@
  1
+# Uninstall hook code here

0 notes on commit db00712

Please sign in to comment.
Something went wrong with that request. Please try again.