Commit 6b41c7515add2dc471417ffb567429786c70ebfa

moved pre_commit library to rspec/pre_commit to support running specs from unpacked gem

git-svn-id: svn+ssh://rubyforge.org/var/svn/rspec/trunk@3257 410327ef-2207-0410-a325-f78bbcb22a5a

Commit diff

Rakefile

 
11dir = File.dirname(__FILE__)
2$LOAD_PATH.unshift(File.expand_path("#{dir}/pre_commit/lib"))
2$LOAD_PATH.unshift(File.expand_path("#{dir}/rspec/pre_commit/lib"))
33require "pre_commit"
44
55task :default => :pre_commit
toggle raw diff

example_rails_app/Multirails.rake

 
11dir = File.dirname(__FILE__)
2$LOAD_PATH.unshift(File.expand_path("#{dir}/../pre_commit/lib"))
2$LOAD_PATH.unshift(File.expand_path("#{dir}/../rspec/pre_commit/lib"))
33require "pre_commit"
44
55desc "Run precommit for all installed versions of Rails"
toggle raw diff

example_rails_app/lib/tasks/bootstrap_rspec.rake

 
11# We have to make sure the rspec lib above gets loaded rather than the gem one (in case it's installed)
22dir = File.dirname(__FILE__)
3$LOAD_PATH.unshift(File.expand_path("#{dir}/../../../pre_commit/lib"))
3$LOAD_PATH.unshift(File.expand_path("#{dir}/../../../rspec/pre_commit/lib"))
44$LOAD_PATH.unshift(File.expand_path("#{dir}/../../../rspec/lib"))
55require "pre_commit"
66require 'spec/rake/spectask'
toggle raw diff

pre_commit/lib/pre_commit.rb

 
0require "pre_commit/pre_commit"
1require "pre_commit/rspec"
2require "pre_commit/core"
3require "pre_commit/rspec_on_rails"
toggle raw diff

pre_commit/lib/pre_commit/core.rb

 
0class PreCommit::Core < PreCommit
1 def pre_commit
2 rake_invoke :examples
3 website
4 end
5
6 def website(run_webby=true)
7 clobber
8 rake_invoke :verify_rcov
9 rake_invoke :spec_html
10 webby
11 rake_invoke :failing_examples_with_html
12 rdoc
13 rdoc_rails
14 end
15
16 def clobber
17 rm_rf '../doc/output'
18 rm_rf 'translated_specs'
19 end
20
21 def webby
22 Dir.chdir '../doc' do
23 output = silent_sh('rake rebuild 2>&1')
24 if shell_error?(output)
25 raise "ERROR while generating web site: #{output}"
26 end
27
28 spec_page = File.expand_path('output/documentation/tools/spec.html')
29 spec_page_content = File.open(spec_page).read
30 unless spec_page_content =~/\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\./m
31 raise "#{'!'*400}\nIt seems like the output in the generated documentation is broken (no dots: ......)\n. Look in #{spec_page}"
32 end
33 end
34 end
35
36 def rdoc
37 Dir.chdir '../rspec' do
38 rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
39 `#{rake} rdoc`
40 end
41 end
42
43 def rdoc_rails
44 Dir.chdir '../rspec_on_rails' do
45 rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
46 `#{rake} rdoc`
47 end
48 end
49end
toggle raw diff

pre_commit/lib/pre_commit/pre_commit.rb

 
0class PreCommit
1 attr_reader :actor
2 def initialize(actor)
3 @actor = actor
4 end
5
6 protected
7 def rake_invoke(task_name)
8 Rake::Task[task_name].invoke
9 end
10
11 def rake_sh(task_name, env_hash={})
12 env = env_hash.collect{|key, value| "#{key}=#{value}"}.join(' ')
13 rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
14 cmd = "#{rake} #{task_name} #{env} --trace"
15 output = silent_sh(cmd)
16 puts output
17 if shell_error?(output)
18 raise "ERROR while running rake: #{cmd}"
19 end
20 end
21
22 def silent_sh(cmd, &block)
23 output = nil
24 IO.popen(cmd) do |io|
25 output = io.read
26 output.each_line do |line|
27 block.call(line) if block
28 end
29 end
30 output
31 end
32
33 def shell_error?(output)
34 output =~ /ERROR/n || error_code?
35 end
36
37 def error_code?
38 $?.exitstatus != 0
39 end
40
41 def root_dir
42 dir = File.dirname(__FILE__)
43 File.expand_path("#{dir}/../../..")
44 end
45
46 def method_missing(method_name, *args, &block)
47 if actor.respond_to?(method_name)
48 actor.send(method_name, *args, &block)
49 else
50 super
51 end
52 end
53end
toggle raw diff

pre_commit/lib/pre_commit/rspec.rb

 
0class PreCommit::Rspec < PreCommit
1 def pre_commit
2 check_for_gem_dependencies
3 fix_cr_lf
4 touch_revision_storing_files
5 pre_commit_core
6 pre_commit_textmate_bundle
7 pre_commit_rails
8 ok_to_commit
9 end
10
11 def check_for_gem_dependencies
12 require "rubygems"
13 gem 'rake'
14 gem 'webby'
15 gem 'coderay'
16 gem 'RedCloth'
17 gem 'syntax'
18 gem 'diff-lcs'
19 gem 'heckle' unless PLATFORM == "i386-mswin32"
20 gem 'hpricot'
21 end
22
23 def fix_cr_lf
24 files = FileList['**/*.rb'].
25 exclude('example_rails_app/vendor/**').
26 exclude('rspec/translated_specs/**')
27 $\="\n"
28 files.each do |f|
29 raw_content = File.read(f)
30 fixed_content = ""
31 raw_content.each_line do |line|
32 fixed_content << line
33 end
34 unless raw_content == fixed_content
35 File.open(f, "w") do |io|
36 io.print fixed_content
37 end
38 end
39 end
40 end
41
42 def touch_revision_storing_files
43 files = [
44 'rspec/lib/spec/version.rb',
45 'rspec_on_rails/lib/spec/rails/version.rb'
46 ]
47 build_time_utc = Time.now.utc.strftime('%Y%m%d%H%M%S')
48 files.each do |path|
49 abs_path = File.join(root_dir, path)
50 content = File.open(abs_path).read
51 touched_content = content.gsub(/BUILD_TIME_UTC = (\d*)\n/n, "BUILD_TIME_UTC = #{build_time_utc}\n")
52 File.open(abs_path, 'w') do |io|
53 io.write touched_content
54 end
55 end
56 end
57
58 def pre_commit_core
59 Dir.chdir 'rspec' do
60 rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
61 system("#{rake} pre_commit --verbose --trace")
62 raise "RSpec Core pre_commit failed" if error_code?
63 end
64 end
65
66 def pre_commit_textmate_bundle
67 Dir.chdir 'RSpec.tmbundle/Support' do
68 rake = (PLATFORM == "i386-mswin32") ? "rake.bat" : "rake"
69 system("#{rake} spec --verbose --trace")
70 raise "RSpec Textmate Bundle specs failed" if error_code?
71 end
72 end
73
74 def install_dependencies
75 Dir.chdir 'example_rails_app' do
76 rake_sh("-f Multirails.rake install_dependencies")
77 end
78 end
79
80 def update_dependencies
81 Dir.chdir 'example_rails_app' do
82 rake_sh("-f Multirails.rake update_dependencies")
83 end
84 end
85
86 def pre_commit_rails
87 Dir.chdir 'example_rails_app' do
88 rake = (PLATFORM == "i386-mswin32") ? "rake.cmd" : "rake"
89 cmd = "#{rake} -f Multirails.rake pre_commit --trace"
90 system(cmd)
91 if error_code?
92 message = <<-EOF
93 ############################################################
94 RSpec on Rails Plugin pre_commit failed. For more info:
95
96 cd example_rails_app
97 #{cmd}
98
99 ############################################################
100 EOF
101 raise message.gsub(/^ /, '')
102 end
103 end
104 end
105
106 def ok_to_commit
107 puts "OK TO COMMIT"
108 end
109end
toggle raw diff

pre_commit/lib/pre_commit/rspec_on_rails.rb

 
0class PreCommit::RspecOnRails < PreCommit
1 def pre_commit
2 install_plugins
3 check_dependencies
4 used_railses = []
5 VENDOR_DEPS.each do |dependency|
6 rails_dir = File.expand_path(dependency[:checkout_path])
7 rails_version = rails_version_from_dir(rails_dir)
8 begin
9 rspec_pre_commit(rails_version, false)
10 used_railses << rails_version
11 rescue => e
12 unless rails_version == 'edge'
13 raise e
14 end
15 end
16 end
17 uninstall_plugins
18 puts "All specs passed against the following released versions of Rails: #{used_railses.join(", ")}"
19 unless used_railses.include?('edge')
20 puts "There were errors running pre_commit against edge"
21 end
22 end
23
24 def rails_version_from_dir(rails_dir)
25 File.basename(rails_dir)
26 end
27
28 def rspec_pre_commit(rails_version=ENV['RSPEC_RAILS_VERSION'],uninstall=true)
29 puts "#####################################################"
30 puts "running pre_commit against rails #{rails_version}"
31 puts "#####################################################"
32 ENV['RSPEC_RAILS_VERSION'] = rails_version
33 cleanup(uninstall)
34 ensure_db_config
35 clobber_sqlite_data
36 install_plugins
37 generate_rspec
38
39 generate_login_controller
40 create_purchase
41
42 rake_sh "spec"
43 rake_sh "spec:plugins:rspec_on_rails"
44
45 # TODO - why is this necessary? Shouldn't the specs leave
46 # a clean DB?
47 rake_sh "db:test:prepare"
48 sh "ruby vendor/plugins/rspec_on_rails/stories/all.rb"
49 cleanup(uninstall)
50 end
51
52 def cleanup(uninstall=true)
53 revert_routes
54 rm_generated_login_controller_files
55 destroy_purchase
56 uninstall_plugins if uninstall
57 end
58
59 def revert_routes
60 output = silent_sh("cp config/routes.rb.bak config/routes.rb")
61 raise "Error reverting routes.rb" if shell_error?(output)
62 end
63
64 def create_purchase
65 generate_purchase
66 migrate_up
67 end
68
69 def install_plugins
70 install_rspec_on_rails_plugin
71 install_rspec_plugin
72 end
73
74 def install_rspec_on_rails_plugin
75 rm_rf 'vendor/plugins/rspec_on_rails'
76 copy '../rspec_on_rails', 'vendor/plugins/'
77 end
78
79 def install_rspec_plugin
80 rm_rf 'vendor/plugins/rspec'
81 copy '../rspec', 'vendor/plugins/'
82 end
83
84 def uninstall_plugins
85 rm_rf 'vendor/plugins/rspec_on_rails'
86 rm_rf 'vendor/plugins/rspec'
87 rm_rf 'script/spec'
88 rm_rf 'script/spec_server'
89 rm_rf 'spec/spec_helper.rb'
90 rm_rf 'spec/spec.opts'
91 rm_rf 'spec/rcov.opts'
92 end
93
94 def copy(source, target)
95 output = silent_sh("cp -R #{File.expand_path(source)} #{File.expand_path(target)}")
96 raise "Error installing rspec" if shell_error?(output)
97 end
98
99 def generate_rspec
100 result = silent_sh("ruby script/generate rspec --force")
101 if error_code? || result =~ /^Missing/
102 raise "Failed to generate rspec environment:\n#{result}"
103 end
104 end
105
106 def ensure_db_config
107 config_path = 'config/database.yml'
108 unless File.exists?(config_path)
109 message = <<-EOF
110 #####################################################
111 Could not find #{config_path}
112
113 You can get rake to generate this file for you using either of:
114 rake rspec:generate_mysql_config
115 rake rspec:generate_sqlite3_config
116
117 If you use mysql, you'll need to create dev and test
118 databases and users for each. To do this, standing
119 in rspec_on_rails, log into mysql as root and then...
120 mysql> source db/mysql_setup.sql;
121
122 There is also a teardown script that will remove
123 the databases and users:
124 mysql> source db/mysql_teardown.sql;
125 #####################################################
126 EOF
127 raise message.gsub(/^ /, '')
128 end
129 end
130
131 def generate_mysql_config
132 copy 'config/database.mysql.yml', 'config/database.yml'
133 end
134
135 def generate_sqlite3_config
136 copy 'config/database.sqlite3.yml', 'config/database.yml'
137 end
138
139 def clobber_db_config
140 rm 'config/database.yml'
141 end
142
143 def clobber_sqlite_data
144 rm_rf 'db/*.db'
145 end
146
147 def generate_purchase
148 generator = "ruby script/generate rspec_scaffold purchase order_id:integer created_at:datetime amount:decimal keyword:string description:text --force"
149 notice = <<-EOF
150 #####################################################
151 #{generator}
152 #####################################################
153 EOF
154 puts notice.gsub(/^ /, '')
155 result = silent_sh(generator)
156 if error_code? || result =~ /not/
157 raise "rspec_scaffold failed. #{result}"
158 end
159 end
160
161 def purchase_migration_version
162 "005"
163 end
164
165 def migrate_up
166 rake_sh "db:migrate"
167 end
168
169 def destroy_purchase
170 migrate_down
171 rm_generated_purchase_files
172 end
173
174 def migrate_down
175 notice = <<-EOF
176 #####################################################
177 Migrating down and reverting config/routes.rb
178 #####################################################
179 EOF
180 puts notice.gsub(/^ /, '')
181 rake_sh "db:migrate", 'VERSION' => (purchase_migration_version.to_i - 1)
182 output = silent_sh("cp config/routes.rb.bak config/routes.rb")
183 raise "revert failed: #{output}" if error_code?
184 end
185
186 def rm_generated_purchase_files
187 puts "#####################################################"
188 puts "Removing generated files:"
189 generated_files = %W{
190 app/helpers/purchases_helper.rb
191 app/models/purchase.rb
192 app/controllers/purchases_controller.rb
193 app/views/purchases
194 db/migrate/#{purchase_migration_version}_create_purchases.rb
195 spec/models/purchase_spec.rb
196 spec/helpers/purchases_helper_spec.rb
197 spec/controllers/purchases_controller_spec.rb
198 spec/controllers/purchases_routing_spec.rb
199 spec/fixtures/purchases.yml
200 spec/views/purchases
201 }
202 generated_files.each do |file|
203 rm_rf file
204 end
205 puts "#####################################################"
206 end
207
208 def generate_login_controller
209 generator = "ruby script/generate rspec_controller login signup login logout --force"
210 notice = <<-EOF
211 #####################################################
212 #{generator}
213 #####################################################
214 EOF
215 puts notice.gsub(/^ /, '')
216 result = silent_sh(generator)
217 if error_code? || result =~ /not/
218 raise "rspec_scaffold failed. #{result}"
219 end
220 end
221
222 def rm_generated_login_controller_files
223 puts "#####################################################"
224 puts "Removing generated files:"
225 generated_files = %W{
226 app/helpers/login_helper.rb
227 app/controllers/login_controller.rb
228 app/views/login
229 spec/helpers/login_helper_spec.rb
230 spec/controllers/login_controller_spec.rb
231 spec/views/login
232 }
233 generated_files.each do |file|
234 rm_rf file
235 end
236 puts "#####################################################"
237 end
238
239 def install_dependencies
240 VENDOR_DEPS.each do |dep|
241 puts "\nChecking for #{dep[:name]} ..."
242 dest = dep[:checkout_path]
243 if File.exists?(dest)
244 puts "#{dep[:name]} already installed"
245 else
246 cmd = "svn co #{dep[:url]} #{dest}"
247 puts "Installing #{dep[:name]}"
248 puts "This may take a while."
249 puts cmd
250 system(cmd)
251 puts "Done!"
252 end
253 end
254 puts
255 end
256
257 def check_dependencies
258 VENDOR_DEPS.each do |dep|
259 unless File.exist?(dep[:checkout_path])
260 raise "There is no checkout of #{dep[:checkout_path]}. Please run rake install_dependencies"
261 end
262 # Verify that the current working copy is right
263 if `svn info #{dep[:checkout_path]}` =~ /^URL: (.*)/
264 actual_url = $1
265 if actual_url != dep[:url]
266 raise "Your working copy in #{dep[:checkout_path]} points to \n#{actual_url}\nIt has moved to\n#{dep[:url]}\nPlease delete the working copy and run rake install_dependencies"
267 end
268 end
269 end
270 end
271
272 def update_dependencies
273 check_dependencies
274 VENDOR_DEPS.each do |dep|
275 next if dep[:tagged?] #
276 puts "\nUpdating #{dep[:name]} ..."
277 dest = dep[:checkout_path]
278 system("svn cleanup #{dest}")
279 cmd = "svn up #{dest}"
280 puts cmd
281 system(cmd)
282 puts "Done!"
283 end
284 end
285
286 VENDOR_DEPS = [
287 {
288 :checkout_path => "vendor/rails/2.0.2",
289 :name => "rails 2.0.2",
290 :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_2-0-2",
291 :tagged? => true
292 },
293 {
294 :checkout_path => "vendor/rails/1.2.6",
295 :name => "rails 1.2.6",
296 :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-6",
297 :tagged? => true
298 },
299 {
300 :checkout_path => "vendor/rails/1.2.3",
301 :name => "rails 1.2.3",
302 :url => "http://dev.rubyonrails.org/svn/rails/tags/rel_1-2-3",
303 :tagged? => true
304 },
305 {
306 :checkout_path => "vendor/rails/edge",
307 :name => "edge rails",
308 :url => "http://svn.rubyonrails.org/rails/trunk",
309 :tagged? => false
310 }
311 ]
312end
toggle raw diff

pre_commit/spec/pre_commit/pre_commit_spec.rb

 
0require File.dirname(__FILE__) + '/../spec_helper.rb'
1
2##
3# This is not a complete specification of PreCommit, but
4# just a collection of bug fix regression tests.
5describe "The helper method PreCommit#silent_sh" do
6 before do
7 @pre_commit = PreCommit.new(nil)
8 end
9
10 # bug in r1802
11 it "should return the command output" do
12 @pre_commit.send(:silent_sh, "echo foo").should ==("foo\n")
13 end
14end
toggle raw diff

pre_commit/spec/pre_commit/rspec_on_rails_spec.rb

 
0require File.dirname(__FILE__) + '/../spec_helper.rb'
1require 'fileutils'
2
3include FileUtils
4
5##
6# This is not a complete specification of PreCommit.RSpecOnRails, but
7# just a collection of bug fix regression tests.
8describe "RSpecOnRails pre_commit" do
9 before do
10 @original_dir = File.expand_path(FileUtils.pwd)
11 @rails_app_dir = File.expand_path(File.dirname(__FILE__) + "/../../../example_rails_app/")
12
13 Dir.chdir(@rails_app_dir)
14 rm_rf('vendor/plugins/rspec_on_rails')
15 system("svn export ../rspec_on_rails vendor/plugins/rspec_on_rails")
16
17 @pre_commit = PreCommit::RspecOnRails.new(nil)
18 end
19
20 after do
21 rm('db/migrate/888_create_purchases.rb', :force => true)
22 @pre_commit.destroy_purchase
23 Dir.chdir(@original_dir)
24 end
25
26 # bug in r1802
27 it "should fail noisily if there is a migration name conflict" do
28 touch('db/migrate/888_create_purchases.rb')
29 lambda { @pre_commit.generate_purchase }.should raise_error
30 end
31
32 it "should not fail if tests run ok" do
33 lambda { @pre_commit.generate_purchase }.should_not raise_error
34 end
35end
toggle raw diff

pre_commit/spec/spec_helper.rb

 
0$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
1require 'pre_commit'
2
toggle raw diff

pre_commit/spec/spec_suite.rb

 
0class SpecSuite
1 def run
2 system("ruby rspec/spec/rspec_suite.rb") || raise("Rspec Suite FAILED")
3 system("ruby rspec_on_rails/spec/rails_suite.rb") || raise("Rails Suite FAILED")
4 system("ruby cached_example_rails_app/spec/rails_app_suite.rb") || raise("Rails App Suite FAILED")
5 end
6end
7
8if $0 == __FILE__
9 SpecSuite.new.run
10end
toggle raw diff

rspec/Rakefile

 
77require 'rake/testtask'
88require 'spec/version'
99dir = File.dirname(__FILE__)
10$LOAD_PATH.unshift(File.expand_path("#{dir}/../pre_commit/lib"))
10$LOAD_PATH.unshift(File.expand_path("#{dir}/pre_commit/lib"))
1111