]> git.wincent.com - wikitext.git/blob - spec/rails_spec.rb
6d7d11c25c24e3cf1785ee5fd27ce5260f3f2f8e
[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     TRASH_PATH + "#{version}-app"
77   end
78
79   def create_rails2_app version
80     app = app_path version
81     clone
82     FileUtils.rm_r(app) if File.exist?(app)
83     FileUtils.cd CLONE_PATH do
84       run 'git', 'checkout', '-f', "v#{version}"
85       run 'git', 'clean', '-f'
86     end
87     run 'ruby', RAILS2_BIN_PATH, app
88     vendor = app + 'vendor'
89     gems = vendor + 'gems'
90     FileUtils.cd vendor do
91       FileUtils.ln_s '../../rails.git', 'rails'
92     end
93     FileUtils.mkdir gems
94     FileUtils.cd gems do
95       FileUtils.ln_s '../../../../..', "wikitext-#{Wikitext::VERSION}"
96     end
97   end
98
99   # if version is nil will create an "Edge" app
100   def create_rails3_app version
101     app = app_path version
102     clone
103     FileUtils.rm_r(app) if File.exist?(app)
104     FileUtils.cd CLONE_PATH do
105       if version
106         run 'git', 'checkout', '-f', "v#{version}"
107       else # "Edge"
108         run 'git', 'checkout', '-f', 'master'
109         run 'git', 'merge', 'origin/master'
110       end
111       run 'git', 'clean', '-f'
112     end
113     run 'ruby', RAILS3_BIN_PATH, 'new', app, '--skip-activerecord', '--dev'
114     create_gemfile app
115   end
116
117   def insert text, after, infile
118     output = []
119     found   = false
120     File.read(infile).split("\n").each do |line|
121       output << line
122       if found == false && line =~ /#{Regexp.escape(after)}/
123         found = true
124         output << text
125       end
126     end
127     File.open(infile, 'wb') { |f| f.write(output.join("\n")) }
128     raise "text '#{after}' not found" unless found
129   end
130
131   # Rails 2 only
132   def add_text_to_initializer text, infile
133     insert text, 'Rails::Initializer.run do', infile
134   end
135
136   # Rails 3 only
137   def add_text_to_routes text, infile
138     insert text, 'Application.routes.draw', infile
139   end
140
141   def create_gemfile app
142     File.open(app + 'Gemfile', 'w') do |f|
143       f.write <<-GEMFILE
144         gem 'rails', :path => "#{CLONE_PATH.realpath}"
145         gem 'wikitext', :path => "#{WIKITEXT_GEM_PATH.realpath}"
146       GEMFILE
147     end
148   end
149
150   def create_controller app
151     File.open(app + 'app' + 'controllers' + 'wiki_controller.rb', 'w') do |f|
152       f.write 'class WikiController < ApplicationController; end'
153     end
154   end
155
156   def create_template app
157     template_dir = app + 'app' + 'views' + 'wiki'
158     FileUtils.mkdir template_dir
159     File.open(template_dir + 'index.html.wikitext', 'w') do |f|
160       f.write '* hello, world!'
161     end
162   end
163
164   def create_test app
165     # integration tests won't run without a schema.rb
166     FileUtils.touch app + 'db' + 'schema.rb'
167
168     File.open(app + 'test' + 'integration' + 'wiki_test.rb', 'w') do |f|
169       f.write <<'TEST'
170 require File.join(File.dirname(__FILE__), '..', 'test_helper')
171
172 class WikiTest < ActionController::IntegrationTest
173   def test_wiki_index
174     get "/wiki"
175     assert_response :success
176     assert_template "wiki/index"
177     assert_select 'ul>li', 'hello, world!'
178   end
179 end
180 TEST
181       end
182   end
183
184   # Rails 2 only
185   def update_environment app
186     environment =  app + 'config' + 'environment.rb'
187     add_text_to_initializer "  config.gem 'wikitext', :version => '#{Wikitext::VERSION}'", environment
188     FileUtils.cd app do
189       run 'rake', 'gems:refresh_specs'
190     end
191   end
192
193   # Rails 3 only
194   def update_routes app
195     routes = app + 'config' + 'routes.rb'
196     add_text_to_routes 'match "/wiki" => "wiki#index"', routes
197   end
198
199   def setup_rails2_app version
200     create_rails2_app version
201     path = app_path version
202     update_environment path
203     create_controller path
204     create_template path
205     create_test path
206   end
207
208   def setup_rails3_app version = nil
209     create_rails3_app version
210     path = app_path version
211     update_routes path
212     create_controller path
213     create_template path
214     create_test path
215   end
216
217   def setup_edge_app
218     setup_rails3_app
219   end
220
221   def run_integration_test app
222     FileUtils.cd app do
223       return run('rake', 'test:integration').stdout
224     end
225   end
226 end # module RailsSpecs
227
228 describe 'Template handler in Rails 2.3.0' do
229   include RailsSpecs
230
231   before :all do
232     setup_rails2_app '2.3.0'
233     @path = app_path '2.3.0'
234   end
235
236   it 'should process the template using the wikitext module' do
237     pending 'Rack::Lint::LintError'
238     # Rack::Lint::LintError: a header value must be a String, but the value of
239     # 'Set-Cookie' is a Array
240     run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
241   end
242 end
243
244 # test other Rails 2 versions
245 %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
246    2.3.7 2.3.8}.each do |version|
247   describe "Template handler in Rails #{version}" do
248     include RailsSpecs
249
250     before :all do
251       setup_rails2_app version
252       @path = app_path version
253     end
254
255     it 'should process the template using the wikitext module' do
256       run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
257     end
258   end
259 end
260
261 describe 'Template handler in Edge Rails' do
262   include RailsSpecs
263
264   before :all do
265     setup_edge_app
266     @path = app_path nil
267   end
268
269   it 'should process the template using the wikitext module' do
270     run_integration_test(@path).should =~ RailsSpecs::SUCCESSFUL_TEST_RESULT
271   end
272 end