Commit 0b054562 by cuong.tran

Merge branch 'release/v2.7.0'

parents d878a5b7 bee8f380
sudo: false
language: ruby
rvm:
- 1.9.3
- 2.0
- 2.1
- 2.2
- 2.3.0-preview1
before_install:
- rvm @global do gem install bundler
== 2.7.0
See https://github.com/ctran/annotate_models/releases/tag/v2.7.0
== 2.6.9
* Support foreigh key (#241)
* Check if model has skip tag in annotate_model_file (#167)
......
source 'https://rubygems.org'
gem 'rake', '>= 0.8.7', :require => false
gem 'activerecord', '>= 2.3.0', :require => false
gem 'rake', '>= 10.4.2', :require => false
gem 'activerecord', '>= 4.2.5', :require => false
group :development do
gem 'mg', :require => false
......@@ -23,6 +23,6 @@ group :development, :test do
end
group :test do
gem 'wrong', '>=0.6.2', :require => false
gem 'files', '>=0.2.1', :require => false
gem 'wrong', :require => false
gem 'files', :require => false
end
......@@ -51,7 +51,7 @@ Also, if you pass the -r option, it'll annotate routes.rb with the output of
Into Gemfile from rubygems.org:
gem 'annotate', '~> 2.6.6'
gem 'annotate'
Into Gemfile from Github:
......@@ -100,9 +100,7 @@ To remove routes.rb annotations:
annotate --routes --delete
== Configuration
To automatically annotate every time you run +db:migrate+, either run +rails g annotate:install+ or add +Annotate.load_tasks+ to your `Rakefile`. See the [configuration in Rails](#configuration-in-rails) section for more info.
=== Usage Outside of Rails
......@@ -112,7 +110,6 @@ or more +--model-dir+ options to inform annotate about the structure of your
project and help it bootstrap and load the relevant code.
== Configuration
If you want to always skip annotations on a particular model, add this string
......@@ -130,7 +127,13 @@ default options:
Edit this file to control things like output format, where annotations are
added (top or bottom of file), and in which artifacts.
== Rails Integration
The generated rakefile +lib/tasks/auto_annotate_models.rake+ also contains
`Annotate.load_tasks`. This adds a few rake tasks which duplicate command-line
functionality:
rake annotate_models # Add schema information (as comments) to model and fixture files
rake annotate_routes # Adds the route map to routes.rb
rake remove_annotation # Remove schema information from model and fixture files
By default, once you've generated a configuration file, annotate will be
executed whenever you run +rake db:migrate+ (but only in development mode).
......
......@@ -27,13 +27,13 @@ Gem::Specification.new do |s|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q<rake>, ["~> 10.4"])
s.add_runtime_dependency(%q<activerecord>, [">= 3.2", "<= 4.3"])
s.add_runtime_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
else
s.add_dependency(%q<rake>, ["~> 10.4"])
s.add_dependency(%q<activerecord>, [">= 3.2", "<= 4.3"])
s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
end
else
s.add_dependency(%q<rake>, [">= 0.8.7"])
s.add_dependency(%q<activerecord>, [">= 3.2", "<= 4.3"])
s.add_dependency(%q<activerecord>, [">= 3.2", "< 6.0"])
end
end
......@@ -18,18 +18,16 @@ require 'optparse'
require 'annotate'
Annotate.bootstrap_rake
target = {
:klass => AnnotateModels,
:task => :do_annotations,
}
has_set_position = {}
target_action = :do_annotations
OptionParser.new do |opts|
opts.banner = "Usage: annotate [options] [model_file]*"
opts.on('-d', '--delete',
"Remove annotations from all model files or the routes.rb file") do
target[:task] = :remove_annotations
target_action = :remove_annotations
end
opts.on('-p', '--position [before|top|after|bottom]', ['before', 'top', 'after', 'bottom'],
......@@ -93,10 +91,7 @@ OptionParser.new do |opts|
opts.on('-r', '--routes',
"Annotate routes.rb with the output of 'rake routes'") do
target = {
:klass => AnnotateRoutes,
:task => :do_annotations
}
ENV['routes'] = 'true'
end
opts.on('-v', '--version',
......@@ -129,6 +124,11 @@ OptionParser.new do |opts|
ENV['model_dir'] = dir
end
opts.on('--root-dir dir',
"Annotate files stored within root dir projects, separate multiple dirs with comas") do |dir|
ENV['root_dir'] = dir
end
opts.on('--ignore-model-subdirects',
"Ignore subdirectories of the models directory") do |dir|
ENV['ignore_model_sub_dir'] = "yes"
......@@ -178,8 +178,18 @@ OptionParser.new do |opts|
ENV['ignore_columns'] = regex
end
opts.on('--hide-limit-column-types VALUES', "don't show limit for given column types, separated by comas (i.e., `integer,boolean,text`)" ) do |values|
ENV['hide_limit_column_types'] = "#{values}"
end
opts.on('--ignore-unknown-models', "don't display warnings for bad model files" ) do |values|
ENV['ignore_unknown_models'] = "true"
end
end.parse!
options = Annotate.setup_options({ :is_rake => ENV['is_rake'] && !ENV['is_rake'].empty? })
Annotate.eager_load(options)
target[:klass].send(target[:task], options)
AnnotateModels.send(target_action, options) if Annotate.include_models?
AnnotateRoutes.send(target_action, options) if Annotate.include_routes?
......@@ -7,7 +7,7 @@ begin
# ActiveSupport 3.x...
require 'active_support/hash_with_indifferent_access'
require 'active_support/core_ext/object/blank'
rescue Exception => e
rescue Exception
# ActiveSupport 2.x...
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/blank'
......@@ -27,32 +27,36 @@ module Annotate
:exclude_fixtures, :exclude_factories, :ignore_model_sub_dir,
:format_bare, :format_rdoc, :format_markdown, :sort, :force, :trace,
:timestamp, :exclude_serializers, :classified_sort, :show_foreign_keys,
:exclude_scaffolds, :exclude_controllers, :exclude_helpers, :ignore_unknown_models,
]
OTHER_OPTIONS=[
:ignore_columns
:ignore_columns, :skip_on_db_migrate, :wrapper_open, :wrapper_close, :wrapper, :routes,
:hide_limit_column_types,
]
PATH_OPTIONS=[
:require, :model_dir
:require, :model_dir, :root_dir
]
##
# Set default values that can be overridden via environment variables.
#
def self.set_defaults(options = {})
return if(@has_set_defaults)
@has_set_defaults = true
options = HashWithIndifferentAccess.new(options)
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
if(options.has_key?(key))
default_value = if(options[key].is_a?(Array))
if options.has_key?(key)
default_value = if options[key].is_a?(Array)
options[key].join(",")
else
options[key]
end
end
default_value = ENV[key.to_s] if(!ENV[key.to_s].blank?)
ENV[key.to_s] = default_value.to_s
default_value = ENV[key.to_s] if !ENV[key.to_s].blank?
ENV[key.to_s] = default_value.nil? ? nil : default_value.to_s
end
end
......@@ -75,13 +79,34 @@ module Annotate
options[:model_dir] = ['app/models']
end
if(options[:root_dir].empty?)
options[:root_dir] = ['']
end
options[:wrapper_open] ||= options[:wrapper]
options[:wrapper_close] ||= options[:wrapper]
return options
end
def self.reset_options
[POSITION_OPTIONS, FLAG_OPTIONS, PATH_OPTIONS, OTHER_OPTIONS].flatten.each do |key|
ENV[key.to_s] = nil
end
end
def self.skip_on_migration?
ENV['skip_on_db_migrate'] =~ TRUE_RE
end
def self.include_routes?
ENV['routes'] =~ TRUE_RE
end
def self.include_models?
true
end
def self.loaded_tasks=(val); @loaded_tasks = val; end
def self.loaded_tasks; return @loaded_tasks; end
......@@ -124,7 +149,7 @@ module Annotate
def self.bootstrap_rake
begin
require 'rake/dsl_definition'
rescue Exception => e
rescue Exception
# We might just be on an old version of Rake...
end
require 'rake'
......
......@@ -37,7 +37,8 @@ module AnnotateRoutes
"#"
] + routes_map.map { |line| "# #{line}".rstrip }
(content, where_header_found) = strip_annotations(File.read(routes_file))
existing_text = File.read(routes_file)
(content, where_header_found) = strip_annotations(existing_text)
changed = where_header_found != 0 # This will either be :before, :after, or
# a number. If the number is > 0, the
# annotation was found somewhere in the
......@@ -60,21 +61,25 @@ module AnnotateRoutes
content = position_after ? (content + header) : header + content
write_contents(content)
puts "Route file annotated."
if write_contents(existing_text, content)
puts "#{routes_file} annotated."
else
puts "#{routes_file} unchanged."
end
end
def self.remove_annotations(options={})
return unless(routes_exists?)
(content, where_header_found) = strip_annotations(File.read(routes_file))
existing_text = File.read(routes_file)
(content, where_header_found) = strip_annotations(existing_text)
content = strip_on_removal(content, where_header_found)
write_contents(content)
puts "Removed annotations from routes file."
if write_contents(existing_text, content)
puts "Removed annotations from #{routes_file}."
else
puts "#{routes_file} unchanged."
end
end
protected
......@@ -89,11 +94,15 @@ protected
return routes_exists
end
def self.write_contents(content)
content << '' unless(content.last == '') # Make sure we end on a trailing
# newline.
def self.write_contents(existing_text, new_content)
# Make sure we end on a trailing newline.
new_content << '' unless(new_content.last == '')
new_text = new_content.join("\n")
return false if existing_text == new_text
File.open(routes_file, "wb") { |f| f.puts(content.join("\n")) }
File.open(routes_file, "wb") { |f| f.puts(new_text) }
return true
end
def self.strip_annotations(content)
......
module Annotate
def self.version
'2.6.10'
'2.7.0'
end
end
......@@ -5,32 +5,42 @@ if Rails.env.development?
task :set_annotation_options do
# You can override any of these by setting an environment variable of the
# same name.
Annotate.set_defaults({
'position_in_routes' => "before",
'position_in_class' => "before",
'position_in_test' => "before",
'position_in_fixture' => "before",
'position_in_factory' => "before",
'position_in_serializer' => "before",
'show_foreign_keys' => "true",
'show_indexes' => "true",
'simple_indexes' => "false",
'model_dir' => "app/models",
'include_version' => "false",
'require' => "",
'exclude_tests' => "false",
'exclude_fixtures' => "false",
'exclude_factories' => "false",
'exclude_serializers' => "false",
'ignore_model_sub_dir' => "false",
'skip_on_db_migrate' => "false",
'format_bare' => "true",
'format_rdoc' => "false",
'format_markdown' => "false",
'sort' => "false",
'force' => "false",
'trace' => "false",
})
Annotate.set_defaults(
'routes' => 'false',
'position_in_routes' => 'before',
'position_in_class' => 'before',
'position_in_test' => 'before',
'position_in_fixture' => 'before',
'position_in_factory' => 'before',
'position_in_serializer' => 'before',
'show_foreign_keys' => 'true',
'show_indexes' => 'true',
'simple_indexes' => 'false',
'model_dir' => 'app/models',
'root_dir' => '',
'include_version' => 'false',
'require' => '',
'exclude_tests' => 'false',
'exclude_fixtures' => 'false',
'exclude_factories' => 'false',
'exclude_serializers' => 'false',
'exclude_scaffolds' => 'false',
'exclude_controllers' => 'false',
'exclude_helpers' => 'false',
'ignore_model_sub_dir' => 'false',
'ignore_columns' => nil,
'ignore_unknown_models' => 'false',
'hide_limit_column_types' => '<%= AnnotateModels::NO_LIMIT_COL_TYPES.join(',') %>',
'skip_on_db_migrate' => 'false',
'format_bare' => 'true',
'format_rdoc' => 'false',
'format_markdown' => 'false',
'sort' => 'false',
'force' => 'false',
'trace' => 'false',
'wrapper_open' => nil,
'wrapper_close' => nil,
)
end
Annotate.load_tasks
......
annotate_lib = File.expand_path(File.dirname(File.dirname(__FILE__)))
if(!ENV['is_cli'])
if !ENV['is_cli']
task :set_annotation_options
task :annotate_models => :set_annotation_options
end
......@@ -17,15 +17,20 @@ task :annotate_models => :environment do
options[:position_in_factory] = Annotate.fallback(ENV['position_in_factory'], ENV['position'])
options[:position_in_test] = Annotate.fallback(ENV['position_in_test'], ENV['position'])
options[:position_in_serializer] = Annotate.fallback(ENV['position_in_serializer'], ENV['position'])
options[:show_foreign_keys] = Annotate.true?(ENV['show_foreign_keys'])
options[:show_indexes] = Annotate.true?(ENV['show_indexes'])
options[:simple_indexes] = Annotate.true?(ENV['simple_indexes'])
options[:model_dir] = ENV['model_dir'] ? ENV['model_dir'].split(',') : []
options[:model_dir] = ENV['model_dir'] ? ENV['model_dir'].split(',') : ['app/models']
options[:root_dir] = ENV['root_dir'] ? ENV['root_dir'].split(',') : ['']
options[:include_version] = Annotate.true?(ENV['include_version'])
options[:require] = ENV['require'] ? ENV['require'].split(',') : []
options[:exclude_tests] = Annotate.true?(ENV['exclude_tests'])
options[:exclude_factories] = Annotate.true?(ENV['exclude_factories'])
options[:exclude_fixtures] = Annotate.true?(ENV['exclude_fixtures'])
options[:exclude_serializers] = Annotate.true?(ENV['exclude_serializers'])
options[:exclude_scaffolds] = Annotate.true?(ENV['exclude_scaffolds'])
options[:exclude_controllers] = Annotate.true?(ENV['exclude_controllers'])
options[:exclude_helpers] = Annotate.true?(ENV['exclude_helpers'])
options[:ignore_model_sub_dir] = Annotate.true?(ENV['ignore_model_sub_dir'])
options[:format_bare] = Annotate.true?(ENV['format_bare'])
options[:format_rdoc] = Annotate.true?(ENV['format_rdoc'])
......@@ -36,6 +41,8 @@ task :annotate_models => :environment do
options[:trace] = Annotate.true?(ENV['trace'])
options[:wrapper_open] = Annotate.fallback(ENV['wrapper_open'], ENV['wrapper'])
options[:wrapper_close] = Annotate.fallback(ENV['wrapper_close'], ENV['wrapper'])
options[:ignore_columns] = ENV.fetch('ignore_columns', nil)
AnnotateModels.do_annotations(options)
end
......@@ -46,6 +53,7 @@ task :remove_annotation => :environment do
options={ :is_rake => true }
options[:model_dir] = ENV['model_dir']
options[:root_dir] = ENV['root_dir']
options[:require] = ENV['require'] ? ENV['require'].split(',') : []
options[:trace] = Annotate.true?(ENV['trace'])
AnnotateModels.remove_annotations(options)
......
......@@ -2,20 +2,23 @@
# (They are not used to build annotate itself.)
# Append annotations to Rake tasks for ActiveRecord, so annotate automatically gets
# run after doing db:migrate.
# Unfortunately it relies on ENV for options; it'd be nice to be able to set options
# in a per-project config file so this task can read them.
# run after doing db:migrate.
namespace :db do
task :migrate do
Annotate::Migration.update_annotations
end
[:migrate, :rollback].each do |cmd|
task cmd do
Rake::Task['set_annotation_options'].invoke
Annotate::Migration.update_annotations
end
namespace :migrate do
[:change, :up, :down, :reset, :redo].each do |t|
task t do
Annotate::Migration.update_annotations
namespace cmd do
[:change, :up, :down, :reset, :redo].each do |t|
task t do
Rake::Task['set_annotation_options'].invoke
Annotate::Migration.update_annotations
end
end
end
end
end
end
......@@ -24,9 +27,25 @@ module Annotate
@@working = false
def self.update_annotations
unless @@working || (ENV['skip_on_db_migrate'] =~ /(true|t|yes|y|1)$/i)
unless @@working || Annotate.skip_on_migration?
@@working = true
Rake::Task['annotate_models'].invoke
self.update_models if Annotate.include_models?
self.update_routes if Annotate.include_routes?
end
end
def self.update_models
if Rake::Task.task_defined?("annotate_models")
Rake::Task["annotate_models"].invoke
elsif Rake::Task.task_defined?("app:annotate_models")
Rake::Task["app:annotate_models"].invoke
end
end
def self.update_routes
if Rake::Task.task_defined?("annotate_routes")
Rake::Task["annotate_routes"].invoke
end
end
end
......
......@@ -2,6 +2,7 @@
require File.dirname(__FILE__) + '/../spec_helper.rb'
require 'annotate/annotate_models'
require 'annotate/active_record_patch'
require 'active_support/core_ext/string'
describe AnnotateModels do
def mock_foreign_key(name, from_column, to_table, to_column = 'id')
......@@ -17,6 +18,7 @@ describe AnnotateModels do
double("Conn",
:indexes => indexes,
:foreign_keys => foreign_keys,
:supports_foreign_keys? => true,
)
end
......@@ -56,11 +58,14 @@ describe AnnotateModels do
it { expect(AnnotateModels.quote(25)).to eql("25") }
it { expect(AnnotateModels.quote(25.6)).to eql("25.6") }
it { expect(AnnotateModels.quote(1e-20)).to eql("1.0e-20") }
it { expect(AnnotateModels.quote(BigDecimal.new("1.2"))).to eql("1.2") }
it { expect(AnnotateModels.quote([BigDecimal.new("1.2")])).to eql(["1.2"]) }
it "should get schema info" do
it "should get schema info with default options" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer),
mock_column(:name, :string, :limit => 50)
mock_column(:id, :integer, :limit => 8),
mock_column(:name, :string, :limit => 50),
mock_column(:notes, :text, :limit => 55),
])
expect(AnnotateModels.get_schema_info(klass, "Schema Info")).to eql(<<-EOS)
......@@ -68,8 +73,9 @@ describe AnnotateModels do
#
# Table name: users
#
# id :integer not null, primary key
# name :string(50) not null
# id :integer not null, primary key
# name :string(50) not null
# notes :text(55) not null
#
EOS
end
......@@ -189,6 +195,61 @@ EOS
EOS
end
describe "#get_schema_info with custom options" do
def self.when_called_with(options = {})
expected = options.delete(:returns)
it "should work with options = #{options}" do
klass = mock_class(:users, :id, [
mock_column(:id, :integer, :limit => 8),
mock_column(:active, :boolean, :limit => 1),
mock_column(:name, :string, :limit => 50),
mock_column(:notes, :text, :limit => 55),
])
schema_info = AnnotateModels.get_schema_info(klass, "Schema Info", options)
expect(schema_info).to eql(expected)
end
end
when_called_with hide_limit_column_types: '', returns: <<-EOS.strip_heredoc
# Schema Info
#
# Table name: users
#
# id :integer not null, primary key
# active :boolean not null
# name :string(50) not null
# notes :text(55) not null
#
EOS
when_called_with hide_limit_column_types: 'integer,boolean', returns:
<<-EOS.strip_heredoc
# Schema Info
#
# Table name: users
#
# id :integer not null, primary key
# active :boolean not null
# name :string(50) not null
# notes :text(55) not null
#
EOS
when_called_with hide_limit_column_types: 'integer,boolean,string,text', returns:
<<-EOS.strip_heredoc
# Schema Info
#
# Table name: users
#
# id :integer not null, primary key
# active :boolean not null
# name :string not null
# notes :text not null
#
EOS
end
describe "#get_model_class" do
require "tmpdir"
......@@ -435,6 +496,35 @@ end
end
end
describe '#resolve_filename' do
it 'should return the test path for a model' do
filename_template = 'test/unit/%MODEL_NAME%_test.rb'
model_name = 'example_model'
table_name = 'example_models'
filename = AnnotateModels.resolve_filename(filename_template, model_name, table_name)
expect(filename). to eq 'test/unit/example_model_test.rb'
end
it 'should return the fixture path for a model' do
filename_template = 'test/fixtures/%TABLE_NAME%.yml'
model_name = 'example_model'
table_name = 'example_models'
filename = AnnotateModels.resolve_filename(filename_template, model_name, table_name)
expect(filename). to eq 'test/fixtures/example_models.yml'
end
it 'should return the fixture path for a nested model' do
filename_template = 'test/fixtures/%PLURALIZED_MODEL_NAME%.yml'
model_name = 'parent/child'
table_name = 'parent_children'
filename = AnnotateModels.resolve_filename(filename_template, model_name, table_name)
expect(filename). to eq 'test/fixtures/parent/children.yml'
end
end
describe "annotating a file" do
before do
@model_dir = Dir.mktmpdir('annotate_models')
......@@ -448,6 +538,7 @@ end
mock_column(:name, :string, :limit => 50)
])
@schema_info = AnnotateModels.get_schema_info(@klass, "== Schema Info")
Annotate.reset_options
end
def write_model file_name, file_content
......@@ -469,14 +560,20 @@ end
Annotate::PATH_OPTIONS.each { |key| ENV[key.to_s] = '' }
end
def encoding_comments_list_each
def magic_comments_list_each
[
'# encoding: UTF-8',
'# coding: UTF-8',
'# -*- coding: UTF-8 -*-',
'#encoding: utf-8',
'# -*- encoding : utf-8 -*-'
].each{|encoding_comment| yield encoding_comment }
'# encoding: utf-8',
'# -*- encoding : utf-8 -*-',
"# encoding: utf-8\n# frozen_string_literal: true",
"# frozen_string_literal: true\n# encoding: utf-8",
'# frozen_string_literal: true',
'#frozen_string_literal: false',
'# -*- frozen_string_literal : true -*-',
].each{|magic_comment| yield magic_comment }
end
it "should put annotation before class if :position == 'before'" do
......@@ -521,7 +618,7 @@ end
it 'should wrap annotation if wrapper is specified' do
annotate_one_file :wrapper_open => 'START', :wrapper_close => 'END'
expect(File.read(@model_file_name)).to eq("# START\n#{@schema_info}\n# END\n#{@file_content}")
expect(File.read(@model_file_name)).to eq("# START\n#{@schema_info}# END\n\n#{@file_content}")
end
describe "with existing annotation => :before" do
......@@ -593,17 +690,22 @@ end
expect(File.read(model_file_name)).to eq("#{schema_info}\n#{file_content}")
end
it "should not touch encoding comments" do
encoding_comments_list_each do |encoding_comment|
it "should not touch magic comments" do
magic_comments_list_each do |magic_comment|
write_model "user.rb", <<-EOS
#{encoding_comment}
#{magic_comment}
class User < ActiveRecord::Base
end
EOS
annotate_one_file :position => :before
expect(File.open(@model_file_name, &:readline)).to eq("#{encoding_comment}\n")
lines= magic_comment.split("\n")
File.open @model_file_name do |file|
lines.count.times do |index|
expect(file.readline).to eq "#{lines[index]}\n"
end
end
end
end
......
......@@ -2,85 +2,114 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
require 'annotate/annotate_routes'
describe AnnotateRoutes do
ROUTE_FILE = "config/routes.rb"
ANNOTATION_ADDED = "#{ROUTE_FILE} annotated."
ANNOTATION_REMOVED = "Removed annotations from #{ROUTE_FILE}."
FILE_UNCHANGED = "#{ROUTE_FILE} unchanged."
def mock_file(stubs={})
@mock_file ||= double(File, stubs)
end
it "should check if routes.rb exists" do
expect(File).to receive(:exists?).with("config/routes.rb").and_return(false)
expect(File).to receive(:exists?).with(ROUTE_FILE).and_return(false)
expect(AnnotateRoutes).to receive(:puts).with("Can`t find routes.rb")
AnnotateRoutes.do_annotations
end
describe "When Annotating, with older Rake Versions" do
describe "When adding" do
before(:each) do
expect(File).to receive(:exists?).with(ROUTE_FILE).and_return(true)
expect(AnnotateRoutes).to receive(:`).with("rake routes").and_return("")
end
it "should insert annotations if file does not contain annotations" do
expect(File).to receive(:read).with(ROUTE_FILE).and_return("")
expect(File).to receive(:open).with(ROUTE_FILE, "wb").and_yield(mock_file)
expect(@mock_file).to receive(:puts).with("\n# == Route Map\n#\n")
expect(AnnotateRoutes).to receive(:puts).with(ANNOTATION_ADDED)
AnnotateRoutes.do_annotations
end
it "should skip annotations if file does already contain annotation" do
expect(File).to receive(:read).with(ROUTE_FILE).and_return("\n# == Route Map\n#\n")
expect(AnnotateRoutes).to receive(:puts).with(FILE_UNCHANGED)
AnnotateRoutes.do_annotations
end
end
describe "When adding with older Rake versions" do
before(:each) do
expect(File).to receive(:exists?).with("config/routes.rb").and_return(true)
expect(File).to receive(:exists?).with(ROUTE_FILE).and_return(true)
expect(AnnotateRoutes).to receive(:`).with("rake routes").and_return("(in /bad/line)\ngood line")
expect(File).to receive(:open).with("config/routes.rb", "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with("Route file annotated.")
expect(File).to receive(:open).with(ROUTE_FILE, "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with(ANNOTATION_ADDED)
end
it "should annotate and add a newline!" do
expect(File).to receive(:read).with("config/routes.rb").and_return("ActionController::Routing...\nfoo")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("ActionController::Routing...\nfoo")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n# == Route Map\n#\n# good line\n/)
AnnotateRoutes.do_annotations
end
it "should not add a newline if there are empty lines" do
expect(File).to receive(:read).with("config/routes.rb").and_return("ActionController::Routing...\nfoo\n")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("ActionController::Routing...\nfoo\n")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n# == Route Map\n#\n# good line\n/)
AnnotateRoutes.do_annotations
end
end
describe "When Annotating, with newer Rake Versions" do
describe "When adding with newer Rake versions" do
before(:each) do
expect(File).to receive(:exists?).with("config/routes.rb").and_return(true)
expect(File).to receive(:exists?).with(ROUTE_FILE).and_return(true)
expect(AnnotateRoutes).to receive(:`).with("rake routes").and_return("another good line\ngood line")
expect(File).to receive(:open).with("config/routes.rb", "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with("Route file annotated.")
expect(File).to receive(:open).with(ROUTE_FILE, "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with(ANNOTATION_ADDED)
end
it "should annotate and add a newline!" do
expect(File).to receive(:read).with("config/routes.rb").and_return("ActionController::Routing...\nfoo")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("ActionController::Routing...\nfoo")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n# == Route Map\n#\n# another good line\n# good line\n/)
AnnotateRoutes.do_annotations
end
it "should not add a newline if there are empty lines" do
expect(File).to receive(:read).with("config/routes.rb").and_return("ActionController::Routing...\nfoo\n")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("ActionController::Routing...\nfoo\n")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n# == Route Map\n#\n# another good line\n# good line\n/)
AnnotateRoutes.do_annotations
end
it "should add a timestamp when :timestamp is passed" do
expect(File).to receive(:read).with("config/routes.rb").and_return("ActionController::Routing...\nfoo")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("ActionController::Routing...\nfoo")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n# == Route Map \(Updated \d{4}-\d{2}-\d{2} \d{2}:\d{2}\)\n#\n# another good line\n# good line\n/)
AnnotateRoutes.do_annotations :timestamp => true
end
end
describe "When Removing Annotation" do
describe "When removing" do
before(:each) do
expect(File).to receive(:exists?).with("config/routes.rb").and_return(true)
expect(File).to receive(:open).with("config/routes.rb", "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with("Removed annotations from routes file.")
expect(File).to receive(:exists?).with(ROUTE_FILE).and_return(true)
expect(File).to receive(:open).with(ROUTE_FILE, "wb").and_yield(mock_file)
expect(AnnotateRoutes).to receive(:puts).with(ANNOTATION_REMOVED)
end
it "should remove trailing annotation and trim trailing newlines, but leave leading newlines alone" do
expect(File).to receive(:read).with("config/routes.rb").and_return("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nActionController::Routing...\nfoo\n\n\n\n\n\n\n\n\n\n\n# == Route Map\n#\n# another good line\n# good line\n")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nActionController::Routing...\nfoo\n\n\n\n\n\n\n\n\n\n\n# == Route Map\n#\n# another good line\n# good line\n")
expect(@mock_file).to receive(:puts).with(/\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nActionController::Routing...\nfoo\n/)
AnnotateRoutes.remove_annotations
end
it "should remove prepended annotation and trim leading newlines, but leave trailing newlines alone" do
expect(File).to receive(:read).with("config/routes.rb").and_return("# == Route Map\n#\n# another good line\n# good line\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nActionController::Routing...\nfoo\n\n\n\n\n\n\n\n\n\n\n")
expect(File).to receive(:read).with(ROUTE_FILE).and_return("# == Route Map\n#\n# another good line\n# good line\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nActionController::Routing...\nfoo\n\n\n\n\n\n\n\n\n\n\n")
expect(@mock_file).to receive(:puts).with(/ActionController::Routing...\nfoo\n\n\n\n\n\n\n\n\n\n\n/)
AnnotateRoutes.remove_annotations
end
......
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