]> git.wincent.com - wikitext.git/blob - spec/rails_spec.rb
Run specs under Rails 3.0.0.beta4
[wikitext.git] / spec / rails_spec.rb
1 # Copyright 2009-2010 Wincent Colaiuta. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are met:
5 #
6 # 1. Redistributions of source code must retain the above copyright notice,
7 #    this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright notice,
9 #    this list of conditions and the following disclaimer in the documentation
10 #    and/or other materials provided with the distribution.
11
12 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
16 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22 # POSSIBILITY OF SUCH DAMAGE.
23
24 require File.join(File.dirname(__FILE__), 'spec_helper.rb')
25 require 'wikitext/version'
26 require 'fileutils'
27 require 'pathname'
28 require 'wopen3'
29 require 'ostruct'
30
31 module RailsSpecs
32   TRASH_PATH              = Pathname.new(__FILE__).dirname + 'trash'
33   CLONE_PATH              = TRASH_PATH + 'rails.git'
34   RAILS2_BIN_PATH         = CLONE_PATH + 'railties' + 'bin' + 'rails'
35   RAILS3_BIN_PATH         = CLONE_PATH + 'bin' + 'rails'
36   WIKITEXT_GEM_PATH       = TRASH_PATH + '..' + '..'
37   SUCCESSFUL_TEST_RESULT  = /1 tests, 3 assertions, 0 failures, 0 errors/
38
39   def run cmd, *args
40     result = OpenStruct.new
41     result.stdout = ''
42     result.stderr = ''
43     Wopen3.popen3(*([cmd] + args)) do |stdin, stdout, stderr|
44       threads = []
45       threads << Thread.new(stdout) do |out|
46         out.each { |line| result.stdout << line }
47       end
48       threads << Thread.new(stderr) do |err|
49         err.each { |line| result.stderr << line }
50       end
51       threads.each { |thread| thread.join }
52     end
53     status = $?.exitstatus
54     if status != 0
55       command_string = ([cmd] + args).join(' ')
56       puts "\n*** COMMAND #{command_string} EXITED WITH NON-ZERO EXIT STATUS (#{status})"
57       puts "*** STDOUT FOR COMMAND #{command_string}:", result.stdout
58       puts "*** STDERR FOR COMMAND #{command_string}:", result.stderr
59       raise "non-zero exit status (#{status}) for '#{cmd}'"
60     end
61     result
62   end
63
64   def clone
65     if File.exist? CLONE_PATH
66       FileUtils.cd CLONE_PATH do
67         run 'git', 'fetch'
68       end
69     else
70       run 'git', 'clone', 'git://github.com/rails/rails.git', CLONE_PATH
71     end
72   end
73
74   def app_path version
75     version = 'edge' if version.nil?
76     version = "v#{version}" if version =~ /\A3\./
77     TRASH_PATH + "#{version}-app"
78   end
79
80   def create_rails2_app version
81     app = app_path version
82     clone
83     FileUtils.rm_r(app) if File.exist?(app)
84     FileUtils.cd CLONE_PATH do
85       run 'git', 'checkout', '-f', "v#{version}"
86       run 'git', 'clean', '-f'
87     end
88     run 'ruby', RAILS2_BIN_PATH, app
89     vendor = app + 'vendor'
90     gems = vendor + 'gems'
91     FileUtils.cd vendor do
92       FileUtils.ln_s '../../rails.git', 'rails'
93     end
94     FileUtils.mkdir gems
95     FileUtils.cd gems do
96       FileUtils.ln_s '../../../../..', "wikitext-#{Wikitext::VERSION}"
97     end
98   end
99
100   # if version is nil will create an "Edge" app
101   def create_rails3_app version
102     app = app_path version
103     clone
104     FileUtils.rm_r(app) if File.exist?(app)
105     FileUtils.cd CLONE_PATH do
106       if version
107         run 'git', 'checkout', '-f', "v#{version}"
108       else # "Edge"
109         run 'git', 'checkout', '-f', 'master'
110         run 'git', 'merge', 'origin/master'
111       end
112       run 'git', 'clean', '-f'
113     end
114     run 'ruby', RAILS3_BIN_PATH, 'new', app, '--skip-activerecord', '--dev'
115     create_gemfile app
116   end
117
118   def insert text, after, infile
119     output = []
120     found   = false
121     File.read(infile).split("\n").each do |line|
122       output << line
123       if found == false && line =~ /#{Regexp.escape(after)}/
124         found = true
125         output << text
126       end
127     end
128     File.open(infile, 'wb') { |f| f.write(output.join("\n")) }
129     raise "text '#{after}' not found" unless found
130   end
131
132   # Rails 2 only
133   def add_text_to_initializer text, infile
134     insert text, 'Rails::Initializer.run do', infile
135   end
136
137   # Rails 3 only
138   def add_text_to_routes text, infile
139     insert text, 'Application.routes.draw', infile
140   end
141
142   def create_gemfile app
143     File.open(app + 'Gemfile', 'w') do |f|
144       f.write <<-GEMFILE
145         gem 'rails', :path => "#{CLONE_PATH.realpath}"
146         gem 'wikitext', :path => "#{WIKITEXT_GEM_PATH.realpath}"
147       GEMFILE
148     end
149   end
150
151   def create_controller app
152     File.open(app + 'app' + 'controllers' + 'wiki_controller.rb', 'w') do |f|
153       f.write 'class WikiController < ApplicationController; end'
154     end
155   end
156
157   def create_template app
158     template_dir = app + 'app' + 'views' + 'wiki'
159     FileUtils.mkdir template_dir
160     File.open(template_dir + 'index.html.wikitext', 'w') do |f|
161       f.write '* hello, world!'
162     end
163   end
164
165   def create_test app
166     # integration tests won't run without a schema.rb
167     FileUtils.touch app + 'db' + 'schema.rb'
168
169     File.open(app + 'test' + 'integration' + 'wiki_test.rb', 'w') do |f|
170       f.write <<'TEST'
171 require File.join(File.dirname(__FILE__), '..', 'test_helper')
172
173 class WikiTest < ActionController::IntegrationTest
174   def test_wiki_index
175     get "/wiki"
176     assert_response :success
177     assert_template "wiki/index"
178     assert_select 'ul>li', 'hello, world!'
179   end
180 end
181 TEST
182       end
183   end
184
185   # Rails 2 only
186   def update_environment app
187     environment =  app + 'config' + 'environment.rb'
188     add_text_to_initializer "  config.gem 'wikitext', :version => '#{Wikitext::VERSION}'", environment
189     FileUtils.cd app do
190       run 'rake', 'gems:refresh_specs'
191     end
192   end
193
194   # Rails 3 only
195   def update_routes app
196     routes = app + 'config' + 'routes.rb'
197     add_text_to_routes 'match "/wiki" => "wiki#index"', routes
198   end
199
200   def setup_rails2_app version
201     create_rails2_app version
202     path = app_path version
203     update_environment path
204     create_controller path
205     create_template path
206     create_test path
207   end
208
209   def setup_rails3_app version = nil
210     create_rails3_app version
211     path = app_path version
212     update_routes path
213     create_controller path
214     create_template path
215     create_test path
216   end
217
218   def setup_edge_app
219     setup_rails3_app
220   end
221
222   def run_integration_test app
223     FileUtils.cd app do
224       return run('rake', 'test:integration').stdout
225     end
226   end
227 end # module RailsSpecs
228
229 describe 'Template handler in Rails 2.3.0' do
230   include RailsSpecs
231
232   before :all do
233     setup_rails2_app '2.3.0'
234     @path = app_path '2.3.0'
235   end
236
237   it 'should process the template using the wikitext module' do
238     pending 'Rack::Lint::LintError'
239     # Rack::Lint::LintError: a header value must be a String, but the value of
240     # 'Set-Cookie' is a Array
241     run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
242   end
243 end
244
245 # test other Rails 2 versions
246 %w{2.2.2 2.2.3 2.3.1 2.3.2 2.3.2.1 2.3.3 2.3.3.1 2.3.4 2.3.5 2.3.6
247    2.3.7 2.3.8}.each do |version|
248   describe "Template handler in Rails #{version}" do
249     include RailsSpecs
250
251     before :all do
252       setup_rails2_app version
253       @path = app_path version
254     end
255
256     it 'should process the template using the wikitext module' do
257       run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
258     end
259   end
260 end
261
262 %w{3.0.0.beta4}.each do |version|
263   describe "Template handler in Rails #{version}" do
264     include RailsSpecs
265
266     before :all do
267       setup_rails3_app version
268       @path = app_path version
269     end
270
271     it 'should process the template using the wikitext module' do
272       run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
273     end
274   end
275 end
276
277 describe 'Template handler in Edge Rails' do
278   include RailsSpecs
279
280   before :all do
281     setup_edge_app
282     @path = app_path nil
283   end
284
285   it 'should process the template using the wikitext module' do
286     run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
287   end
288 end