diff --git a/.gitignore b/.gitignore index 4cc58d6..89d1742 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ -pkg -doc +spec/database.yml +Gemfile.lock +.bundle +*.gem tmp/* *.sqlite3 -database.yml nbproject +*.swp +**/*.swp diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..4e1e0d2 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--color diff --git a/.rvmrc b/.rvmrc new file mode 100644 index 0000000..c4fd407 --- /dev/null +++ b/.rvmrc @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# adapted from: http://rvm.beginrescueend.com/workflow/rvmrc/ + +ruby_string="1.9.2" +gemset_name="populator" + +if rvm list strings | grep -q "${ruby_string}" ; then + + # Load or create the specified environment + if [[ -d "${rvm_path:-$HOME/.rvm}/environments" \ + && -s "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}" ]] ; then + \. "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}" + else + rvm --create "${ruby_string}@${gemset_name}" + fi + +else + + # Notify the user to install the desired interpreter before proceeding. + echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory." + +fi diff --git a/CHANGELOG b/CHANGELOG.rdoc similarity index 92% rename from CHANGELOG rename to CHANGELOG.rdoc index 2fad374..a65cc2a 100644 --- a/CHANGELOG +++ b/CHANGELOG.rdoc @@ -1,29 +1,38 @@ +1.0.0 (not yet released) + +* adding PostgreSQL adapter (thanks phlawski) + * adding Oracle adapter (thanks Andrew N) + 0.2.4 (September 9th, 2008) * removing echoe from gem development dependencies, which didn't seem to work in the first place. * adding Populator.paragraphs to generate paragraphs of text + 0.2.3 (September 2nd, 2008) * support single table inhertance by setting inheritance_column to class name * support custom primary_key in model if they don't use "id" + 0.2.2 (September 1st, 2008) * performance improvements * improving inline documentation + 0.2.1 (August 30th, 2008) * wrap sqlite inserts in transaction to improve performance * default created_at/on and updated_at/on columns to current time + 0.2.0 (August 30th, 2008) * adding :per_query option to limit how many inserts are made per query @@ -34,6 +43,7 @@ * adding Populator.words to fetch some random words + 0.1.0 (August 27th, 2008) * initial release diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c80ee36 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source "http://rubygems.org" + +gemspec diff --git a/LICENSE b/LICENSE index 6b51834..485ab61 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2008 Ryan Bates +Copyright (c) 2011 Ryan Bates Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Manifest b/Manifest deleted file mode 100644 index 03c73ac..0000000 --- a/Manifest +++ /dev/null @@ -1,27 +0,0 @@ -CHANGELOG -lib/populator/adapters/abstract.rb -lib/populator/adapters/oracle.rb -lib/populator/adapters/sqlite.rb -lib/populator/factory.rb -lib/populator/model_additions.rb -lib/populator/random.rb -lib/populator/record.rb -lib/populator.rb -LICENSE -Manifest -Rakefile -README.rdoc -spec/database.yml -spec/example_database.yml -spec/models/category.rb -spec/models/product.rb -spec/populator/factory_spec.rb -spec/populator/model_additions_spec.rb -spec/populator/random_spec.rb -spec/populator/record_spec.rb -spec/README -spec/spec.opts -spec/spec_helper.rb -tasks/deployment.rake -tasks/spec.rake -TODO diff --git a/README.rdoc b/README.rdoc index ff81ded..21c4391 100644 --- a/README.rdoc +++ b/README.rdoc @@ -4,7 +4,7 @@ Populate an Active Record database with mass insert. You can find the rdocs at http://populator.rubyforge.org. -Special thanks to Zach Dennis for his ar-extensions gem which some of +Special thanks to Zach Dennis for his ar-extensions gem which some of this code is loosely based on. @@ -21,8 +21,8 @@ And then load it in your project: == Usage -This gem adds a "populate" method to all Active Record models. Pass the -number of records you want to create along with a block. In the block +This gem adds a "populate" method to all Active Record models. Pass the +number of records you want to create along with a block. In the block you can set the column values for each record. Person.populate(3000) do |person| @@ -50,10 +50,10 @@ Passing a range or array of values will randomly select one. person.annual_income = 10000..200000 end -This will create 1000 to 5000 men or women with the annual income +This will create 1000 to 5000 men or women with the annual income between 10,000 and 200,000. -You can pass a :per_query option to limit how many records are saved +You can pass a :per_query option to limit how many records are saved per query. This defaults to 1000. Person.populate(2000, :per_query => 100) @@ -72,8 +72,8 @@ http://faker.rubyforge.org == Important -For performance reasons, this gem does not use actual instances of the -model. This means validations and callbacks are bypassed. It is up to +For performance reasons, this gem does not use actual instances of the +model. This means validations and callbacks are bypassed. It is up to you to ensure you're adding valid data. @@ -87,5 +87,5 @@ http://github.com/ryanb/populator If you find a bug, please send me a message on GitHub. -If you would like to contribute to this project, please fork the +If you would like to contribute to this project, please fork the repository and send me a pull request. diff --git a/Rakefile b/Rakefile index 32d2200..6987115 100644 --- a/Rakefile +++ b/Rakefile @@ -1,15 +1,23 @@ require 'rubygems' require 'rake' -require 'echoe' - -Echoe.new('populator', '0.2.4') do |p| - p.summary = "Mass populate an Active Record database." - p.description = "Mass populate an Active Record database." - p.url = "http://github.com/ryanb/populator" - p.author = 'Ryan Bates' - p.email = "ryan (at) railscasts (dot) com" - p.ignore_pattern = ["script/*", "**/*.sqlite3", "tmp/*"] - p.development_dependencies = [] -end +require 'rspec/core/rake_task' + +ADAPTERS = YAML.load(File.read(File.dirname(__FILE__) + "/../spec/database.yml")).keys + +desc "Run specs under all supported databases" +task :spec => ADAPTERS.map { |a| "spec:#{a}" } -Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext } +namespace :spec do + ADAPTERS.each do |adapter| + namespace :prepare do + task adapter do + ENV["POPULATOR_ADAPTER"] = adapter + end + end + + desc "Run specs under #{adapter}" + RSpec::Core::RakeTask.new(adapter => "spec:prepare:#{adapter}") do |t| + t.verbose = false + end + end +end diff --git a/TODO b/TODO deleted file mode 100644 index c82f817..0000000 --- a/TODO +++ /dev/null @@ -1,11 +0,0 @@ -Possible -- randomly fill every column if no block is passed to populate -- add random_foo method to record for randomly generating content - -Support Environments -- sqlite 2 -- old rails -- edge rails - -Tests -- add db:reset, db:drop and db:create rake tasks diff --git a/lib/populator/adapters/abstract.rb b/lib/populator/adapters/abstract.rb index 86dddf3..92c0f2b 100644 --- a/lib/populator/adapters/abstract.rb +++ b/lib/populator/adapters/abstract.rb @@ -5,7 +5,7 @@ module Abstract def execute_batch(sql, name = nil) raise NotImplementedError, "execute_batch is an abstract method" end - + def populate(table, columns, rows, name = nil) execute("INSERT INTO #{table} #{columns} VALUES #{rows.join(', ')}", name) end diff --git a/lib/populator/adapters/oracle.rb b/lib/populator/adapters/oracle.rb index caf6fb9..a58000d 100644 --- a/lib/populator/adapters/oracle.rb +++ b/lib/populator/adapters/oracle.rb @@ -1,8 +1,8 @@ module Populator module Adapters - module Oracle + module Oracle - # Executes SQL statements one at a time. + # Executes SQL statements one at a time. def populate(table, columns, rows, name = nil) rows.each do |row| @@ -24,4 +24,3 @@ class OracleAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter end end end - diff --git a/lib/populator/adapters/postgresql.rb b/lib/populator/adapters/postgresql.rb index 7dcf9ef..01322a5 100644 --- a/lib/populator/adapters/postgresql.rb +++ b/lib/populator/adapters/postgresql.rb @@ -19,4 +19,4 @@ class PostgreSQLAdapter < ActiveRecord::ConnectionAdapters::AbstractAdapter include Populator::Adapters::Postgresql end end -end \ No newline at end of file +end diff --git a/lib/populator/adapters/sqlite.rb b/lib/populator/adapters/sqlite.rb index 6655c26..4c82328 100644 --- a/lib/populator/adapters/sqlite.rb +++ b/lib/populator/adapters/sqlite.rb @@ -9,7 +9,7 @@ def execute_batch(sql, name = nil) end end end - + def populate(table, columns, rows, name = nil) queries = [] rows.each do |row| diff --git a/lib/populator/factory.rb b/lib/populator/factory.rb index 574e4c8..02decee 100644 --- a/lib/populator/factory.rb +++ b/lib/populator/factory.rb @@ -2,17 +2,17 @@ module Populator # Builds multiple Populator::Record instances and saves them to the database class Factory DEFAULT_RECORDS_PER_QUERY = 1000 - + @factories = {} @depth = 0 - + # Fetches the factory dedicated to a given model class. You should always use this # method instead of instatiating a factory directly so that a single factory is # shared on multiple calls. def self.for_model(model_class) @factories[model_class] ||= new(model_class) end - + # Find all remaining factories and call save_records on them. def self.save_remaining_records @factories.values.each do |factory| @@ -20,7 +20,7 @@ def self.save_remaining_records end @factories = {} end - + # Keep track of nested factory calls so we can save the remaining records once we # are done with the base factory. This makes Populator more efficient when nesting # factories. @@ -30,20 +30,20 @@ def self.remember_depth @depth -= 1 save_remaining_records if @depth.zero? end - + # Use for_model instead of instatiating a record directly. def initialize(model_class) @model_class = model_class @records = [] end - + # Entry method for building records. Delegates to build_records after remember_depth. def populate(amount, options = {}, &block) self.class.remember_depth do build_records(Populator.interpret_value(amount), options[:per_query] || DEFAULT_RECORDS_PER_QUERY, &block) end end - + # Builds multiple Populator::Record instances and calls save_records them when # :per_query limit option is reached. def build_records(amount, per_query, &block) @@ -54,7 +54,7 @@ def build_records(amount, per_query, &block) save_records if @records.size >= per_query end end - + # Saves the records to the database by calling populate on the current database adapter. def save_records unless @records.empty? @@ -63,23 +63,23 @@ def save_records @records.clear end end - + private - + def quoted_column_names @model_class.column_names.map do |column_name| @model_class.connection.quote_column_name(column_name) end end - + def last_id_in_database @last_id_in_database ||= @model_class.connection.select_value("SELECT id FROM #{@model_class.quoted_table_name} ORDER BY id DESC", "#{@model_class.name} Last ID").to_i end - + def columns_sql "(#{quoted_column_names.join(', ')})" end - + def rows_sql_arr @records.map do |record| quoted_attributes = record.attribute_values.map { |v| @model_class.sanitize(v) } diff --git a/lib/populator/random.rb b/lib/populator/random.rb index 65bf1fb..9ebccac 100644 --- a/lib/populator/random.rb +++ b/lib/populator/random.rb @@ -3,7 +3,7 @@ module Populator # called directly on Populator. module Random WORDS = %w(alias consequatur aut perferendis sit voluptatem accusantium doloremque aperiam eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo aspernatur aut odit aut fugit sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt neque dolorem ipsum quia dolor sit amet consectetur adipisci velit sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem ut enim ad minima veniam quis nostrum exercitationem ullam corporis nemo enim ipsam voluptatem quia voluptas sit suscipit laboriosam nisi ut aliquid ex ea commodi consequatur quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae et iusto odio dignissimos ducimus qui blanditiis praesentium laudantium totam rem voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident sed ut perspiciatis unde omnis iste natus error similique sunt in culpa qui officia deserunt mollitia animi id est laborum et dolorum fuga et harum quidem rerum facilis est et expedita distinctio nam libero tempore cum soluta nobis est eligendi optio cumque nihil impedit quo porro quisquam est qui minus id quod maxime placeat facere possimus omnis voluptas assumenda est omnis dolor repellendus temporibus autem quibusdam et aut consequatur vel illum qui dolorem eum fugiat quo voluptas nulla pariatur at vero eos et accusamus officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae itaque earum rerum hic tenetur a sapiente delectus ut aut reiciendis voluptatibus maiores doloribus asperiores repellat) - + # Pick a random value out of a given range. def value_in_range(range) case range.first @@ -13,13 +13,13 @@ def value_in_range(range) else range.to_a.rand end end - + # Generate a given number of words. If a range is passed, it will generate # a random number of words within that range. def words(total) (1..interpret_value(total)).map { WORDS.rand }.join(' ') end - + # Generate a given number of sentences. If a range is passed, it will generate # a random number of sentences within that range. def sentences(total) @@ -27,7 +27,7 @@ def sentences(total) words(5..20).capitalize end.join('. ') end - + # Generate a given number of paragraphs. If a range is passed, it will generate # a random number of paragraphs within that range. def paragraphs(total) @@ -35,7 +35,7 @@ def paragraphs(total) sentences(3..8).capitalize end.join("\n\n") end - + # If an array or range is passed, a random value will be selected to match. # All other values are simply returned. def interpret_value(value) @@ -45,17 +45,17 @@ def interpret_value(value) else value end end - + private - + def time_in_range(range) Time.at number_in_range(Range.new(range.first.to_i, range.last.to_i, range.exclude_end?)) end - + def date_in_range(range) Date.jd number_in_range(Range.new(range.first.jd, range.last.jd, range.exclude_end?)) end - + def number_in_range(range) if range.exclude_end? rand(range.last - range.first) + range.first @@ -64,6 +64,6 @@ def number_in_range(range) end end end - + extend Random # load it into the populator module directly so we can call the methods end diff --git a/lib/populator/record.rb b/lib/populator/record.rb index e59c474..5560c1b 100644 --- a/lib/populator/record.rb +++ b/lib/populator/record.rb @@ -2,7 +2,7 @@ module Populator # This is what is passed to the block when calling populate. class Record attr_accessor :attributes - + # Creates a new instance of Record. Some attributes are set by default: # # * id - defaults to id passed @@ -25,33 +25,33 @@ def initialize(model_class, id) end end end - + # override id since method_missing won't catch this column name def id @attributes[:id] end - + # override type since method_missing won't catch this column name def type @attributes[:type] end - + # Return values for all columns inside an array. def attribute_values @columns.map do |column| @attributes[column.to_sym] end end - + def attributes=(values_hash) values_hash.each_pair do |key, value| value = value.call if value.is_a?(Proc) self.send((key.to_s + "=").to_sym, value) end end - + private - + def method_missing(sym, *args, &block) name = sym.to_s if @columns.include?(name.sub('=', '')) diff --git a/populator.gemspec b/populator.gemspec new file mode 100644 index 0000000..389dc53 --- /dev/null +++ b/populator.gemspec @@ -0,0 +1,18 @@ +Gem::Specification.new do |s| + s.name = "populator" + s.version = "1.0.0.beta1" + s.author = "Ryan Bates" + s.email = "ryan@railscasts.com" + s.homepage = "http://github.com/ryanb/populator" + s.summary = "Mass populate an Active Record database." + s.description = "Mass populate an Active Record database." + + s.files = Dir["{lib,spec}/**/*", "[A-Z]*", "init.rb"] - ["spec/test.sqlite3"] + s.require_path = "lib" + + s.add_development_dependency 'rspec', '~> 2.1.0' + s.add_development_dependency 'rails', '~> 3.0.0' + + s.rubyforge_project = s.name + s.required_rubygems_version = ">= 1.3.4" +end diff --git a/script/benchmarker b/script/benchmarker deleted file mode 100755 index 55a9f5e..0000000 --- a/script/benchmarker +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env ruby -if ARGV.empty? - puts "Usage: ./script/benchmarker [times] 'Person.expensive_way' 'Person.another_expensive_way' ..." - exit 1 -end - -begin - N = Integer(ARGV.first) - ARGV.shift -rescue ArgumentError - N = 1 -end - -# load the spec_helper file even though this isn't necessarily for specs -# it's just a convenient, quick way to load all the requirements. -require File.dirname(__FILE__) + '/../spec/spec_helper' -require 'benchmark' -include Benchmark - -# Don't include compilation in the benchmark -ARGV.each { |expression| eval(expression) } - -# Ensure we're running on a clean database -[Product, Category].each(&:delete_all) - -bm(6) do |x| - ARGV.each_with_index do |expression, idx| - x.report("##{idx + 1}") { N.times { eval(expression) } } - end -end diff --git a/script/console b/script/console deleted file mode 100755 index cf86b08..0000000 --- a/script/console +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env ruby -# File: script/console -irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb' - -# loading the spec_helper file even though this isn't necessarily for specs -# it's just a convenient, quick way to load all the requirements. -puts "Loading populator gem" -exec "#{irb} -r irb/completion -r #{File.dirname(__FILE__) + '/../spec/spec_helper.rb'} --simple-prompt" diff --git a/script/destroy b/script/destroy deleted file mode 100755 index e48464d..0000000 --- a/script/destroy +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) - -begin - require 'rubigen' -rescue LoadError - require 'rubygems' - require 'rubigen' -end -require 'rubigen/scripts/destroy' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] -RubiGen::Scripts::Destroy.new.run(ARGV) diff --git a/script/generate b/script/generate deleted file mode 100755 index c27f655..0000000 --- a/script/generate +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env ruby -APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..')) - -begin - require 'rubigen' -rescue LoadError - require 'rubygems' - require 'rubigen' -end -require 'rubigen/scripts/generate' - -ARGV.shift if ['--help', '-h'].include?(ARGV[0]) -RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit] -RubiGen::Scripts::Generate.new.run(ARGV) diff --git a/script/profiler b/script/profiler deleted file mode 100755 index da41c79..0000000 --- a/script/profiler +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env ruby -if ARGV.empty? - $stderr.puts "Usage: ./script/profiler [times] 'Person.expensive_method(10)'" - exit(1) -end - -# load the spec_helper file even though this isn't necessarily for specs -# it's just a convenient, quick way to load all the requirements. -require File.dirname(__FILE__) + '/../spec/spec_helper' - -repeat = ARGV.first.to_i > 1 ? ARGV.shift.to_i : 1 -snippet = ARGV.shift - -# Define a method to profile. -eval "def profile_me() #{repeat}.times { #{snippet} } end" - -# Ensure we're running on a clean database -[Product, Category].each(&:delete_all) - -require "ruby-prof" -RubyProf.measure_mode = RubyProf::WALL_TIME -RubyProf.start -profile_me -printer = RubyProf::GraphHtmlPrinter.new(RubyProf.stop) - -Dir.mkdir('tmp') unless File.exist? 'tmp' -File.open('tmp/profile.html', 'w') do |file| - printer.print(file) -end -`open tmp/profile.html &` diff --git a/script/setup b/script/setup deleted file mode 100755 index 3b309ef..0000000 --- a/script/setup +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cp spec/example_database.yml spec/database.yml -echo "Now configure spec/database.yml and create your databases." diff --git a/spec/README b/spec/README.rdoc similarity index 50% rename from spec/README rename to spec/README.rdoc index 258769a..b897b0a 100644 --- a/spec/README +++ b/spec/README.rdoc @@ -1,14 +1,11 @@ -Running Specs -------------- += Running Populator Specs -To prepare the specs, run this command. +To prepare the specs, run the following commands. - script/setup - -This will generate the spec/database.yml file. Configure this to work -with your databases. You can add and remove entries here as well to -test different databases. A rake task is available to run the specs for -each database. + bundle + cp spec/example_database.yml spec/database.yml + +Configure the database.yml file to work with your databases. You can add and remove entries here as well to test different databases. A rake task is available to run the specs for each database. rake spec # Run specs under all databases rake spec:mysql # Run specs under mysql @@ -16,8 +13,7 @@ each database. rake spec:postgresql # Run specs under postgresql ... -Don't forget to create the user and database as necessary. You can do -so under MySQL with these commands. +Don't forget to create the user and database as necessary. You can do so under MySQL with these commands. CREATE DATABASE populator_test; GRANT ALL ON populator_test.* TO populator@localhost; diff --git a/spec/example_database.yml b/spec/example_database.yml index 46681b7..a276d47 100644 --- a/spec/example_database.yml +++ b/spec/example_database.yml @@ -9,7 +9,7 @@ mysql: adapter: mysql database: populator_test username: populator - password: + password: host: localhost postgresql: diff --git a/spec/models/category.rb b/spec/models/category.rb index 90dccdc..baf5670 100644 --- a/spec/models/category.rb +++ b/spec/models/category.rb @@ -8,7 +8,7 @@ def self.up t.string :name end end - + def self.down drop_table :categories end diff --git a/spec/models/product.rb b/spec/models/product.rb index c43504f..3d4af67 100644 --- a/spec/models/product.rb +++ b/spec/models/product.rb @@ -15,7 +15,7 @@ def self.up t.integer :category_id end end - + def self.down drop_table :products end diff --git a/spec/populator/factory_spec.rb b/spec/populator/factory_spec.rb index 061bc4e..2a1c90c 100644 --- a/spec/populator/factory_spec.rb +++ b/spec/populator/factory_spec.rb @@ -5,13 +5,13 @@ before(:each) do @factory = Populator::Factory.for_model(Product) end - + it "should only use one query when inserting records" do $queries_executed = [] @factory.populate(5) $queries_executed.grep(/^insert/i).should have(1).record end - + it "should start id at 1 and increment when table is empty" do Product.delete_all expected_id = 1 @@ -20,7 +20,7 @@ expected_id += 1 end end - + it "should start id at last id and increment" do Product.delete_all product = Product.create @@ -30,21 +30,21 @@ expected_id += 1 end end - + it "should generate within range" do Product.delete_all @factory.populate(2..4) Product.count.should >= 2 Product.count.should <= 4 end - + it "should limit number of records per query" do $queries_executed = [] @factory.populate(5, :per_query => 2) $queries_executed.grep(/^insert/i).should have(3).records end end - + it "should only use two queries when nesting factories (one for each class)" do $queries_executed = [] Populator::Factory.for_model(Category).populate(3) do |category| @@ -54,7 +54,7 @@ end $queries_executed.grep(/^insert/i).should have(2).records end - + it "should only use one query when nesting factories of the same type" do $queries_executed = [] Populator::Factory.for_model(Product).populate(3) do |product| @@ -62,7 +62,7 @@ end $queries_executed.grep(/^insert/i).should have(1).record end - + it "should default to 1000 records per query" do Populator::Factory::DEFAULT_RECORDS_PER_QUERY.should == 1000 end diff --git a/spec/populator/model_additions_spec.rb b/spec/populator/model_additions_spec.rb index 5d08d05..c5d0e81 100644 --- a/spec/populator/model_additions_spec.rb +++ b/spec/populator/model_additions_spec.rb @@ -4,26 +4,26 @@ it "should add populate method to active record class" do Product.should respond_to(:populate) end - + it "should add 10 records to database" do Product.delete_all Product.populate(10) Product.count.should == 10 end - + it "should set attribute columns" do Product.populate(1) do |product| product.name = "foo" end Product.last.name.should == "foo" end - + it "should not pass in an instance of Active Record for performance reasons" do Product.populate(1) do |product| product.should_not be_kind_of(ActiveRecord::Base) end end - + it "should not pass options hash" do $queries_executed = [] Product.populate(5, :per_query => 2) do |product| diff --git a/spec/populator/random_spec.rb b/spec/populator/random_spec.rb index b0f9885..1d11253 100644 --- a/spec/populator/random_spec.rb +++ b/spec/populator/random_spec.rb @@ -5,44 +5,44 @@ Populator.expects(:rand).with(5).returns(3) Populator.value_in_range(10...15).should == 13 end - + it "should pick a random number in range including last value" do Populator.expects(:rand).with(5).returns(3) Populator.value_in_range(10..14).should == 13 end - + it "should pick a random time in range" do start_time = 2.days.ago end_time = Time.now Populator.expects(:rand).with(end_time.to_i-start_time.to_i).returns(1) Populator.value_in_range(start_time...end_time).should == Time.at(start_time.to_i + 1) end - + it "should pick a random date in range" do start_date = 2.years.ago.to_date end_date = Date.today Populator.expects(:rand).with(end_date.jd-start_date.jd).returns(1) Populator.value_in_range(start_date...end_date).should == Date.jd(start_date.jd + 1) end - + it "should pick a random string by converting to array" do Kernel.expects(:rand).with(5).returns(2) Populator.value_in_range('a'..'e').should == 'c' end - + it "should pick 3 random words" do Populator.words(3).split.should have(3).records end - + it "should pick a random number of random words" do Populator.expects(:rand).with(5).returns(3) Populator.words(10...15).split.should have(13).records end - + it "should generate 3 random sentences" do Populator.sentences(3).split(/\. [A-Z]/).should have(3).records end - + it "should generate 3 random paragraphs" do Populator.paragraphs(3).split(/\n\n/).should have(3).records end diff --git a/spec/populator/record_spec.rb b/spec/populator/record_spec.rb index b443dfa..47553c7 100644 --- a/spec/populator/record_spec.rb +++ b/spec/populator/record_spec.rb @@ -8,31 +8,31 @@ record.send(column).should == "foo" end end - + it "should return attribute values in same order as columns" do record = Populator::Record.new(Product, nil) record.name = "foo" expected = Product.column_names.map { |c| "foo" if c == 'name' } record.attribute_values.should == expected end - + it "should assign second parameter to id" do Populator::Record.new(Product, 2).id.should == 2 end - + it "should pick random number from range" do record = Populator::Record.new(Product, 1) record.stock = 2..5 record.stock.should >= 2 record.stock.should <= 5 end - + it "should pick random value from array" do record = Populator::Record.new(Product, 1) record.name = %w[foo bar] %w[foo bar].should include(record.name) end - + it "should automatically set created/updated columns" do Product.stubs(:column_names).returns(%w[id created_at updated_at created_on updated_on]) record = Populator::Record.new(Product, 1) @@ -41,31 +41,31 @@ record.created_on.should == Date.today record.updated_on.should == Date.today end - + it "should use custom primary_key for auto-increment if specified" do Product.stubs(:primary_key).returns('foo') Product.stubs(:column_names).returns(['foo', 'name']) Populator::Record.new(Product, 123).foo.should == 123 end - + it "should default type to class name" do Product.stubs(:column_names).returns(['id', 'type']) Populator::Record.new(Product, 1).type.should == 'Product' end - + it "should default specified inheritance_column to class name" do Product.stubs(:inheritance_column).returns('foo') Product.stubs(:column_names).returns(['id', 'foo']) Populator::Record.new(Product, 1).foo.should == 'Product' end - + it "should allow set via attributes hash" do record = Populator::Record.new(Product, 1) record.attributes = {:stock => 2..5} record.stock.should >= 2 record.stock.should <= 5 end - + it "should take a proc object via attributes hash" do record = Populator::Record.new(Product, 1) record.attributes = {:stock => lambda {15}} diff --git a/spec/spec.opts b/spec/spec.opts deleted file mode 100644 index 5052887..0000000 --- a/spec/spec.opts +++ /dev/null @@ -1 +0,0 @@ ---color \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d24ef7f..fd25c5e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -16,18 +16,18 @@ unless ActiveRecord::Base.connection.respond_to? :record_query ActiveRecord::Base.connection.class.class_eval do IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^begin /i, /^commit /i] - + def record_query(sql) $queries_executed ||= [] $queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r } end - + def execute_with_query_record(*args, &block) record_query(args.first) execute_without_query_record(*args, &block) end alias_method_chain :execute, :query_record - + def execute_batch_with_query_record(*args, &block) record_query(args.first) execute_batch_without_query_record(*args, &block) diff --git a/tasks/deployment.rake b/tasks/deployment.rake deleted file mode 100644 index 8976a29..0000000 --- a/tasks/deployment.rake +++ /dev/null @@ -1,2 +0,0 @@ -desc "Build the manifest and gemspec files." -task :build => [:build_manifest, :build_gemspec] diff --git a/tasks/spec.rake b/tasks/spec.rake deleted file mode 100644 index 691106e..0000000 --- a/tasks/spec.rake +++ /dev/null @@ -1,22 +0,0 @@ -require 'spec/rake/spectask' - -ADAPTERS = YAML.load(File.read(File.dirname(__FILE__) + "/../spec/database.yml")).keys - -desc "Run specs under all supported databases" -task :spec => ADAPTERS.map { |a| "spec:#{a}" } - -namespace :spec do - ADAPTERS.each do |adapter| - namespace :prepare do - task adapter do - ENV["POPULATOR_ADAPTER"] = adapter - end - end - - desc "Run specs under #{adapter}" - Spec::Rake::SpecTask.new(adapter => "spec:prepare:#{adapter}") do |t| - t.spec_files = Rake::FileList["spec/**/*_spec.rb"] - t.spec_opts = ["-c"] - end - end -end