Commit 6e41ec0a by Jon Frisby

Merge remote-tracking branch 'miyucy/restart'

WARNING: EVIL MERGE. I'm fixing a number of problems with this branch and ommitting one or two things. Conflicts: .gitignore History.txt README.rdoc Rakefile VERSION.yml annotate.gemspec lib/annotate/annotate_models.rb lib/tasks/annotate_models.rake lib/tasks/annotate_routes.rake lib/tasks/migrate.rake spec/annotate/annotate_models_spec.rb spec/spec_helper.rb
parents cc7f3b15 280a9e56
...@@ -3,6 +3,7 @@ source :rubygems ...@@ -3,6 +3,7 @@ source :rubygems
group :development do group :development do
gem 'jeweler' gem 'jeweler'
gem 'rspec' gem 'rspec'
gem 'fakefs', :require => false
end end
gem 'active_support' gem 'activesupport', :require => nil
...@@ -5,6 +5,7 @@ GEM ...@@ -5,6 +5,7 @@ GEM
activesupport (= 3.0.0) activesupport (= 3.0.0)
activesupport (3.0.0) activesupport (3.0.0)
diff-lcs (1.1.3) diff-lcs (1.1.3)
fakefs (0.4.0)
git (1.2.5) git (1.2.5)
jeweler (1.6.4) jeweler (1.6.4)
bundler (~> 1.0) bundler (~> 1.0)
...@@ -25,5 +26,6 @@ PLATFORMS ...@@ -25,5 +26,6 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
active_support active_support
fakefs
jeweler jeweler
rspec rspec
...@@ -24,6 +24,20 @@ ...@@ -24,6 +24,20 @@
* Rename "annotate" bin to "annotate_models" to avoid conflicting with * Rename "annotate" bin to "annotate_models" to avoid conflicting with
ImageMagick. ImageMagick.
== 2.4.2 2009-11-21
* Annotates (spec|test)/factories/<model>_factory.rb files
== 2.4.1 2009-11-20
* Annotates thoughtbot's factory_girl factories (test/factories/<model>_factory.rb)
* Move default annotation position back to top
== 2.4.0 2009-12-13
* Incorporated lots of patches from the Github community, including support for Blueprints fixtures
* Several bug fixes
== 2.1 2009-10-18 == 2.1 2009-10-18
* New options * New options
......
...@@ -8,6 +8,7 @@ Add a comment summarizing the current schema to the top or bottom of each of you ...@@ -8,6 +8,7 @@ Add a comment summarizing the current schema to the top or bottom of each of you
* Object Daddy exemplars * Object Daddy exemplars
* Machinist blueprints * Machinist blueprints
* Fabrication fabricators * Fabrication fabricators
* Thoughtbot's factory_girl factories, i.e. the (spec|test)/factories/<model>_factory.rb files
The schema comment looks like this: The schema comment looks like this:
...@@ -96,7 +97,8 @@ you can use to tailor the output. ...@@ -96,7 +97,8 @@ you can use to tailor the output.
-s, --simple-indexes Concat the column's related indexes in the annotation -s, --simple-indexes Concat the column's related indexes in the annotation
--model-dir dir Annotate model files stored in dir rather than app/models --model-dir dir Annotate model files stored in dir rather than app/models
-R, --require path Additional files to require before loading models -R, --require path Additional files to require before loading models
-e, --exclude [tests,fixtures] Do not annotate fixtures, test files, or both -e [tests,fixtures,factories] Do not annotate fixtures, test files, and/or factories
--exclude
== WARNING == WARNING
...@@ -110,7 +112,7 @@ to an automatically created comment block. ...@@ -110,7 +112,7 @@ to an automatically created comment block.
== LINKS == LINKS
* Factory Girl => http://github.com/thoughtbot/factory_girl (NOT IMPLEMENTED) * Factory Girl => http://github.com/thoughtbot/factory_girl
* Object Daddy => http://github.com/flogic/object_daddy * Object Daddy => http://github.com/flogic/object_daddy
* Machinist => http://github.com/notahat/machinist * Machinist => http://github.com/notahat/machinist
* Fabrication => http://github.com/paulelliott/fabrication * Fabrication => http://github.com/paulelliott/fabrication
...@@ -144,6 +146,7 @@ Modifications by: ...@@ -144,6 +146,7 @@ Modifications by:
- Bob Potter - http://github.com/bpot - Bob Potter - http://github.com/bpot
- Gavin Montague - http://github.com/govan/ - Gavin Montague - http://github.com/govan/
- Alexander Semyonov - http://github.com/rotuka/ - Alexander Semyonov - http://github.com/rotuka/
- Nathan Brazil - http://github.com/bitaxis/
- Ian Duggan http://github.com/ijcd/ - Ian Duggan http://github.com/ijcd/
- Jon Frisby http://github.com/mrjoy/ - Jon Frisby http://github.com/mrjoy/
......
...@@ -32,12 +32,6 @@ RSpec::Core::RakeTask.new(:spec) do |t| ...@@ -32,12 +32,6 @@ RSpec::Core::RakeTask.new(:spec) do |t|
t.pattern = ['spec/*_spec.rb', 'spec/**/*_spec.rb'] t.pattern = ['spec/*_spec.rb', 'spec/**/*_spec.rb']
end end
# FIXME not working yet
RSpec::Core::RakeTask.new(:rcov) do |t|
t.pattern = 'spec/**/*_spec.rb'
t.rcov = true
end
# FIXME warns "already initialized constant Task" # FIXME warns "already initialized constant Task"
# FIXME throws "uninitialized constant RDoc::VISIBILITIES" # FIXME throws "uninitialized constant RDoc::VISIBILITIES"
# require 'rdoc/task' # require 'rdoc/task'
......
--- ---
:major: 2 :major: 2
:minor: 4 :minor: 4
:patch: 1 :patch: 2
:build: 'beta1'
\ No newline at end of file
...@@ -5,13 +5,14 @@ ...@@ -5,13 +5,14 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "annotate" s.name = "annotate"
s.version = "2.4.1.beta1" s.version = "2.4.2"
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini", "Turadg Aleahmad"] s.authors = ["Cuong Tran", "Alex Chaffee", "Marcos Piccinini", "Turadg Aleahmad"]
s.date = "2012-03-01" s.date = "2012-03-01"
s.description = "When run, inserts table descriptions from db.schema into a comment block of relevant source code." s.description = "When run, inserts table descriptions from db.schema into a comment block of relevant source code."
s.email = ["alex@stinky.com", "ctran@pragmaquest.com", "x@nofxx.com", "turadg@aleahmad.net"] s.email = ["alex@stinky.com", "ctran@pragmaquest.com", "x@nofxx.com", "turadg@aleahmad.net"]
s.executables = ["annotate_models"]
s.extra_rdoc_files = [ s.extra_rdoc_files = [
"README.rdoc" "README.rdoc"
] ]
...@@ -24,6 +25,7 @@ Gem::Specification.new do |s| ...@@ -24,6 +25,7 @@ Gem::Specification.new do |s|
"Rakefile", "Rakefile",
"VERSION.yml", "VERSION.yml",
"annotate.gemspec", "annotate.gemspec",
"bin/annotate_models",
"lib/annotate.rb", "lib/annotate.rb",
"lib/annotate/active_record_patch.rb", "lib/annotate/active_record_patch.rb",
"lib/annotate/annotate_models.rb", "lib/annotate/annotate_models.rb",
......
...@@ -10,48 +10,48 @@ task = :annotate_models ...@@ -10,48 +10,48 @@ task = :annotate_models
OptionParser.new do |opts| OptionParser.new do |opts|
opts.banner = "Usage: annotate_models [options] [model_file]*" opts.banner = "Usage: annotate_models [options] [model_file]*"
opts.on('-d', '--delete', opts.on('-d', '--delete',
"Remove annotations from all model files") do "Remove annotations from all model files") do
task = :remove_annotation task = :remove_annotation
end end
opts.on('-p', '--position [before|after]', ['before', 'after'], opts.on('-p', '--position [before|after]', ['before', 'after'],
"Place the annotations at the top (before) or the bottom (after) of the model file") do |p| "Place the annotations at the top (before) or the bottom (after) of the model file") do |p|
ENV['position'] = p ENV['position'] = p
end end
opts.on('-r', '--routes', opts.on('-r', '--routes',
"Annotate routes.rb with the output of 'rake routes'") do "Annotate routes.rb with the output of 'rake routes'") do
task = :annotate_routes task = :annotate_routes
end end
opts.on('-v', '--version', opts.on('-v', '--version',
"Show the current version of this gem") do "Show the current version of this gem") do
puts "annotate v#{Annotate.version}"; exit puts "annotate v#{Annotate.version}"; exit
end end
opts.on('-m', '--show-migration', opts.on('-m', '--show-migration',
"Include the migration version number in the annotation") do "Include the migration version number in the annotation") do
ENV['include_version'] = "yes" ENV['include_version'] = "yes"
end end
opts.on('-i', '--show-indexes', opts.on('-i', '--show-indexes',
"List the table's database indexes in the annotation") do "List the table's database indexes in the annotation") do
ENV['show_indexes'] = "yes" ENV['show_indexes'] = "yes"
end end
opts.on('-s', '--simple-indexes', opts.on('-s', '--simple-indexes',
"Concat the column's related indexes in the annotation") do "Concat the column's related indexes in the annotation") do
ENV['simple_indexes'] = "yes" ENV['simple_indexes'] = "yes"
end end
opts.on('--model-dir dir', opts.on('--model-dir dir',
"Annotate model files stored in dir rather than app/models") do |dir| "Annotate model files stored in dir rather than app/models") do |dir|
ENV['model_dir'] = dir ENV['model_dir'] = dir
end end
opts.on('-R', '--require path', opts.on('-R', '--require path',
"Additional files to require before loading models") do |path| "Additional files to require before loading models") do |path|
if ENV['require'] if ENV['require']
ENV['require'] = ENV['require'] + ",#{path}" ENV['require'] = ENV['require'] + ",#{path}"
else else
...@@ -63,6 +63,10 @@ OptionParser.new do |opts| ...@@ -63,6 +63,10 @@ OptionParser.new do |opts|
exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" } exclusions.each { |exclusion| ENV["exclude_#{exclusion}"] = "yes" }
end end
opts.on('-f', '--format [bare|rdoc]', ['bare', 'rdoc'], 'rdoc: render Schema Infomation as RDoc') do |fmt|
ENV['format_#{fmt}'] = 'yes'
end
end.parse! end.parse!
if Annotate.load_tasks if Annotate.load_tasks
......
$:.unshift(File.dirname(__FILE__)) unless
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
require 'yaml' require 'yaml'
......
...@@ -8,6 +8,7 @@ task :annotate_models => :environment do ...@@ -8,6 +8,7 @@ task :annotate_models => :environment do
options={} options={}
options[:position_in_class] = ENV['position_in_class'] || ENV['position'] || 'before' options[:position_in_class] = ENV['position_in_class'] || ENV['position'] || 'before'
options[:position_in_fixture] = ENV['position_in_fixture'] || ENV['position'] || 'before' options[:position_in_fixture] = ENV['position_in_fixture'] || ENV['position'] || 'before'
options[:position_in_factory] = ENV['position_in_factory'] || ENV['position'] || 'before'
options[:show_indexes] = ENV['show_indexes'] =~ true_re options[:show_indexes] = ENV['show_indexes'] =~ true_re
options[:simple_indexes] = ENV['simple_indexes'] =~ true_re options[:simple_indexes] = ENV['simple_indexes'] =~ true_re
options[:model_dir] = ENV['model_dir'] options[:model_dir] = ENV['model_dir']
......
desc "Prepends the route map to the top of routes.rb" desc "Prepends the route map to the top of routes.rb"
task :annotate_routes do task :annotate_routes => :environment do
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'annotate', 'annotate_routes')) require File.expand_path(File.join(File.dirname(__FILE__), '..', 'annotate', 'annotate_routes'))
AnnotateRoutes.do_annotate AnnotateRoutes.do_annotate
end end
#encoding: utf-8
require File.dirname(__FILE__) + '/../spec_helper.rb' require File.dirname(__FILE__) + '/../spec_helper.rb'
require 'annotate/annotate_models' require 'annotate/annotate_models'
require 'annotate/active_record_patch' require 'annotate/active_record_patch'
require 'rubygems'
require 'active_support'
describe AnnotateModels do describe AnnotateModels do
def mock_class(table_name, primary_key, columns)
options = {
:connection => mock("Conn", :indexes => []),
:table_name => table_name,
:primary_key => primary_key.to_s,
:column_names => columns.map { |col| col.name.to_s },
:columns => columns
}
def mock_klass(stubs={}) mock("An ActiveRecord class", options)
@mock_file ||= mock("Klass", stubs)
end end
def mock_column(stubs={}) def mock_column(name, type, options={})
@mock_column ||= mock("Column", stubs) default_options = {
:limit => nil,
:null => false,
:default => nil
}
stubs = default_options.dup
stubs.merge!(options)
stubs.merge!(:name => name, :type => type)
mock("Column", stubs)
end end
it { AnnotateModels.quote(nil).should eql("NULL") } it { AnnotateModels.quote(nil).should eql("NULL") }
...@@ -22,43 +38,54 @@ describe AnnotateModels do ...@@ -22,43 +38,54 @@ describe AnnotateModels do
it { AnnotateModels.quote(1e-20).should eql("1.0e-20") } it { AnnotateModels.quote(1e-20).should eql("1.0e-20") }
it "should get schema info" do it "should get schema info" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
])
AnnotateModels.get_schema_info(mock_klass( AnnotateModels.get_schema_info(klass, "Schema Info").should eql(<<-EOS)
:connection => mock("Conn", :indexes => []),
:table_name => "users",
:primary_key => "id",
:column_names => ["id","login"],
:columns => [
mock_column(:type => "integer", :default => nil, :null => false, :name => "id", :limit => nil),
mock_column(:type => "string", :default => nil, :null => false, :name => "name", :limit => 50)
]), "Schema Info").should eql(<<-EOS)
# Schema Info # Schema Info
# #
# Table name: users # Table name: users
# #
# id :integer not null, primary key # id :integer not null, primary key
# id :integer not null, primary key # name :string(50) not null
# #
EOS EOS
end
it "should get schema info as RDoc" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
])
ENV.stub!(:[]).with('format_rdoc').and_return(true)
AnnotateModels.get_schema_info(klass, AnnotateModels::PREFIX).should eql(<<-EOS)
# #{AnnotateModels::PREFIX}
#
# Table name: users
#
# *id*:: <tt>integer, not null, primary key</tt>
# *name*:: <tt>string(50), not null</tt>
#--
# #{AnnotateModels::END_MARK}
#++
EOS
end end
describe "#get_model_class" do describe "#get_model_class" do
require "tmpdir" require "tmpdir"
module ::ActiveRecord
class Base
end
end
def create(file, body="hi") def create(file, body="hi")
file_path = File.join(AnnotateModels.model_dir, file) file_path = File.join(AnnotateModels.model_dir, file)
FileUtils.mkdir_p(File.dirname(file_path)) FileUtils.mkdir_p(File.dirname(file_path))
File.open(file_path, "w") do |f| File.open(file_path, "wb") do |f|
f.puts(body) f.puts(body)
end end
file_path
end end
def check_class_name(file, class_name) def check_class_name(file, class_name)
...@@ -80,15 +107,6 @@ EOS ...@@ -80,15 +107,6 @@ EOS
check_class_name 'foo.rb', 'Foo' check_class_name 'foo.rb', 'Foo'
end end
it "should not care about unknown macros" do
create 'foo_with_macro.rb', <<-EOS
class FooWithMacro < ActiveRecord::Base
acts_as_awesome :yah
end
EOS
check_class_name 'foo_with_macro.rb', 'FooWithMacro'
end
it "should find models with non standard capitalization" do it "should find models with non standard capitalization" do
create 'foo_with_capitals.rb', <<-EOS create 'foo_with_capitals.rb', <<-EOS
class FooWithCAPITALS < ActiveRecord::Base class FooWithCAPITALS < ActiveRecord::Base
...@@ -107,6 +125,25 @@ EOS ...@@ -107,6 +125,25 @@ EOS
check_class_name 'bar/foo_inside_bar.rb', 'Bar::FooInsideBar' check_class_name 'bar/foo_inside_bar.rb', 'Bar::FooInsideBar'
end end
it "should not care about unknown macros" do
create 'foo_with_macro.rb', <<-EOS
class FooWithMacro < ActiveRecord::Base
acts_as_awesome :yah
end
EOS
check_class_name 'foo_with_macro.rb', 'FooWithMacro'
end
it "should not complain of invalid multibyte char (USASCII)" do
create 'foo_with_utf8.rb', <<-EOS
#encoding: utf-8
class FooWithUtf8 < ActiveRecord::Base
UTF8STRINGS = %w[résumé façon âge]
end
EOS
check_class_name 'foo_with_utf8.rb', 'FooWithUtf8'
end
it "should find models inside modules with non standard capitalization" do it "should find models inside modules with non standard capitalization" do
create 'bar/foo_inside_capitals_bar.rb', <<-EOS create 'bar/foo_inside_capitals_bar.rb', <<-EOS
module BAR module BAR
...@@ -132,61 +169,114 @@ EOS ...@@ -132,61 +169,114 @@ EOS
EOS EOS
check_class_name 'bar/non_namespaced_foo_with_capitals_inside_bar.rb', 'NonNamespacedFooWithCapitalsInsideBar' check_class_name 'bar/non_namespaced_foo_with_capitals_inside_bar.rb', 'NonNamespacedFooWithCapitalsInsideBar'
end end
end
it "should not get confused by existing annotations on a model when the schema changes" do describe "#remove_annotation_of_file" do
create 'foo.rb', <<-EOS require "tmpdir"
class Foo < ActiveRecord::Base
end
# == Schema Information
#
# Table name: users
#
# id :integer(4) not null, primary key
# name :string
#
# Indexes
#
# index_users_on_name (name) UNIQUE
#
EOS def create(file, body="hi")
path = File.join(@dir, file)
File.open(path, "w") do |f|
f.puts(body)
end
return path
end
def content(path)
File.read(path)
end
before :each do
@dir = Dir.mktmpdir 'annotate_models'
end
info_block = <<-EOS it "should remove before annotate" do
path = create "before.rb", <<-EOS
# == Schema Information # == Schema Information
# #
# Table name: users # Table name: foo
#
# id :integer(4) not null, primary key
# name :string
# new :string
#
# Indexes
# #
# index_users_on_name (name) UNIQUE # id :integer not null, primary key
# created_at :datetime
# updated_at :datetime
# #
EOS class Foo < ActiveRecord::Base
fname = File.join(AnnotateModels.model_dir, 'foo.rb') end
EOS
AnnotateModels.annotate_one_file(fname, info_block).should be_true AnnotateModels.remove_annotation_of_file(path)
content(path).should == <<-EOS
class Foo < ActiveRecord::Base
end
EOS
end
File.read(fname).should == <<-EOS it "should remove after annotate" do
path = create "after.rb", <<-EOS
class Foo < ActiveRecord::Base class Foo < ActiveRecord::Base
end end
# == Schema Information # == Schema Information
# #
# Table name: users # Table name: foo
#
# id :integer(4) not null, primary key
# name :string
# new :string
#
# Indexes
# #
# index_users_on_name (name) UNIQUE # id :integer not null, primary key
# created_at :datetime
# updated_at :datetime
# #
EOS EOS
AnnotateModels.remove_annotation_of_file(path)
content(path).should == <<-EOS
class Foo < ActiveRecord::Base
end
EOS
end
end
describe "annotating a file" do
before do
@file_name = File.join(Dir.mktmpdir('annotate_models'), "user.rb")
@file_content = <<-EOS
class User < ActiveRecord::Base
end
EOS
File.open(@file_name, "wb") { |f| f.write @file_content }
@klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
])
@schema_info = AnnotateModels.get_schema_info(@klass, "== Schema Info")
end
it "should annotate the file before the model if position == 'before'" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => "before")
File.read(@file_name).should == "#{@schema_info}#{@file_content}"
end
it "should annotate before if given :position => :before" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :before)
File.read(@file_name).should == "#{@schema_info}#{@file_content}"
end
it "should annotate before if given :position => :after" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :after)
File.read(@file_name).should == "#{@file_content}\n#{@schema_info}"
end
it "should update annotate position" do
AnnotateModels.annotate_one_file(@file_name, @schema_info, :position => :before)
another_schema_info = AnnotateModels.get_schema_info(mock_class(:users, :id, [mock_column(:id, :integer),]),
"== Schema Info")
AnnotateModels.annotate_one_file(@file_name, another_schema_info, :position => :after)
File.read(@file_name).should == "#{@file_content}\n#{another_schema_info}"
end end
end end
end end
--format=specdoc
--colour --colour
\ No newline at end of file
...@@ -7,5 +7,6 @@ rescue LoadError ...@@ -7,5 +7,6 @@ rescue LoadError
end end
$:.unshift(File.dirname(__FILE__) + '/../lib') $:.unshift(File.dirname(__FILE__) + '/../lib')
require 'bigdecimal' require 'active_support'
require 'active_support/core_ext/string/inflections'
require 'annotate' require 'annotate'
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment