sinatra-base 1.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +4 -0
- data/AUTHORS +15 -0
- data/CHANGES +524 -1
- data/Gemfile +82 -0
- data/LICENSE +1 -1
- data/README.de.rdoc +2093 -0
- data/README.es.rdoc +2091 -0
- data/README.fr.rdoc +2116 -0
- data/README.hu.rdoc +607 -0
- data/README.jp.rdoc +514 -23
- data/README.pt-br.rdoc +647 -0
- data/README.pt-pt.rdoc +646 -0
- data/README.rdoc +1580 -205
- data/README.ru.rdoc +2015 -0
- data/README.zh.rdoc +1816 -0
- data/Rakefile +110 -44
- data/examples/chat.rb +61 -0
- data/examples/simple.rb +3 -0
- data/examples/stream.ru +26 -0
- data/lib/sinatra.rb +0 -3
- data/lib/sinatra/base.rb +923 -393
- data/lib/sinatra/main.rb +9 -7
- data/lib/sinatra/showexceptions.rb +37 -4
- data/lib/sinatra/version.rb +3 -0
- data/sinatra-base.gemspec +15 -91
- data/test/base_test.rb +2 -2
- data/test/builder_test.rb +32 -2
- data/test/coffee_test.rb +92 -0
- data/test/contest.rb +62 -28
- data/test/creole_test.rb +65 -0
- data/test/delegator_test.rb +162 -0
- data/test/encoding_test.rb +20 -0
- data/test/erb_test.rb +25 -2
- data/test/extensions_test.rb +1 -1
- data/test/filter_test.rb +226 -8
- data/test/haml_test.rb +8 -2
- data/test/helper.rb +47 -0
- data/test/helpers_test.rb +1287 -80
- data/test/integration/app.rb +62 -0
- data/test/integration_helper.rb +208 -0
- data/test/integration_test.rb +82 -0
- data/test/less_test.rb +36 -6
- data/test/liquid_test.rb +59 -0
- data/test/mapped_error_test.rb +84 -7
- data/test/markaby_test.rb +80 -0
- data/test/markdown_test.rb +81 -0
- data/test/middleware_test.rb +1 -1
- data/test/nokogiri_test.rb +69 -0
- data/test/rack_test.rb +45 -0
- data/test/radius_test.rb +59 -0
- data/test/rdoc_test.rb +66 -0
- data/test/readme_test.rb +136 -0
- data/test/request_test.rb +13 -1
- data/test/response_test.rb +21 -2
- data/test/result_test.rb +5 -5
- data/test/route_added_hook_test.rb +1 -1
- data/test/routing_test.rb +328 -13
- data/test/sass_test.rb +48 -18
- data/test/scss_test.rb +88 -0
- data/test/server_test.rb +4 -3
- data/test/settings_test.rb +191 -21
- data/test/sinatra_test.rb +5 -1
- data/test/slim_test.rb +88 -0
- data/test/static_test.rb +89 -5
- data/test/streaming_test.rb +140 -0
- data/test/templates_test.rb +143 -4
- data/test/textile_test.rb +65 -0
- data/test/views/a/in_a.str +1 -0
- data/test/views/ascii.erb +2 -0
- data/test/views/b/in_b.str +1 -0
- data/test/views/calc.html.erb +1 -0
- data/test/views/explicitly_nested.str +1 -0
- data/test/views/hello.coffee +1 -0
- data/test/views/hello.creole +1 -0
- data/test/views/hello.liquid +1 -0
- data/test/views/hello.mab +1 -0
- data/test/views/hello.md +1 -0
- data/test/views/hello.nokogiri +1 -0
- data/test/views/hello.radius +1 -0
- data/test/views/hello.rdoc +1 -0
- data/test/views/hello.sass +1 -1
- data/test/views/hello.scss +3 -0
- data/test/views/hello.slim +1 -0
- data/test/views/hello.str +1 -0
- data/test/views/hello.textile +1 -0
- data/test/views/hello.yajl +1 -0
- data/test/views/layout2.liquid +2 -0
- data/test/views/layout2.mab +2 -0
- data/test/views/layout2.nokogiri +3 -0
- data/test/views/layout2.radius +2 -0
- data/test/views/layout2.slim +3 -0
- data/test/views/layout2.str +2 -0
- data/test/views/nested.str +1 -0
- data/test/views/utf8.erb +2 -0
- data/test/yajl_test.rb +80 -0
- metadata +126 -91
- data/lib/sinatra/tilt.rb +0 -746
- data/test/erubis_test.rb +0 -82
- data/test/views/error.erubis +0 -3
- data/test/views/hello.erubis +0 -1
- data/test/views/layout2.erubis +0 -2
@@ -0,0 +1,62 @@
|
|
1
|
+
$stderr.puts "loading"
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
configure do
|
5
|
+
set :foo, :bar
|
6
|
+
end
|
7
|
+
|
8
|
+
get '/app_file' do
|
9
|
+
content_type :txt
|
10
|
+
settings.app_file
|
11
|
+
end
|
12
|
+
|
13
|
+
get '/ping' do
|
14
|
+
'pong'
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/stream' do
|
18
|
+
stream do |out|
|
19
|
+
sleep 0.1
|
20
|
+
out << "a"
|
21
|
+
sleep 1.2
|
22
|
+
out << "b"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
get '/mainonly' do
|
27
|
+
object = Object.new
|
28
|
+
begin
|
29
|
+
object.send(:get, '/foo') { }
|
30
|
+
'false'
|
31
|
+
rescue NameError
|
32
|
+
'true'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
set :out, nil
|
37
|
+
get '/async' do
|
38
|
+
stream(:keep_open) { |o| (settings.out = o) << "hi!" }
|
39
|
+
end
|
40
|
+
|
41
|
+
get '/send' do
|
42
|
+
settings.out << params[:msg] if params[:msg]
|
43
|
+
settings.out.close if params[:close]
|
44
|
+
"ok"
|
45
|
+
end
|
46
|
+
|
47
|
+
class Subclass < Sinatra::Base
|
48
|
+
set :out, nil
|
49
|
+
get '/subclass/async' do
|
50
|
+
stream(:keep_open) { |o| (settings.out = o) << "hi!" }
|
51
|
+
end
|
52
|
+
|
53
|
+
get '/subclass/send' do
|
54
|
+
settings.out << params[:msg] if params[:msg]
|
55
|
+
settings.out.close if params[:close]
|
56
|
+
"ok"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
use Subclass
|
61
|
+
|
62
|
+
$stderr.puts "starting"
|
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'rbconfig'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module IntegrationHelper
|
7
|
+
class BaseServer
|
8
|
+
extend Enumerable
|
9
|
+
attr_accessor :server, :port, :pipe
|
10
|
+
alias name server
|
11
|
+
|
12
|
+
def self.all
|
13
|
+
@all ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.each(&block)
|
17
|
+
all.each(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.run(server, port)
|
21
|
+
new(server, port).run
|
22
|
+
end
|
23
|
+
|
24
|
+
def app_file
|
25
|
+
File.expand_path('../integration/app.rb', __FILE__)
|
26
|
+
end
|
27
|
+
|
28
|
+
def environment
|
29
|
+
"development"
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(server, port)
|
33
|
+
@installed, @pipe, @server, @port = nil, nil, server, port
|
34
|
+
Server.all << self
|
35
|
+
end
|
36
|
+
|
37
|
+
def run
|
38
|
+
return unless installed?
|
39
|
+
kill
|
40
|
+
@log = ""
|
41
|
+
@pipe = IO.popen(command)
|
42
|
+
@started = Time.now
|
43
|
+
warn "#{server} up and running on port #{port}" if ping
|
44
|
+
at_exit { kill }
|
45
|
+
end
|
46
|
+
|
47
|
+
def expect(str)
|
48
|
+
return if log.size < str.size or log[0, str.size] == str
|
49
|
+
raise "Server did not start properly:\n\n#{log}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def ping(timeout = 10)
|
53
|
+
loop do
|
54
|
+
return if alive?
|
55
|
+
if Time.now - @started > timeout
|
56
|
+
$stderr.puts command, log
|
57
|
+
get('/ping')
|
58
|
+
else
|
59
|
+
expect "loading"
|
60
|
+
sleep 0.1
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def alive?
|
66
|
+
3.times { get('/ping') }
|
67
|
+
true
|
68
|
+
rescue Errno::ECONNREFUSED, Errno::ECONNRESET, EOFError, SystemCallError => error
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_stream(url = "/stream", &block)
|
73
|
+
Net::HTTP.start '127.0.0.1', port do |http|
|
74
|
+
request = Net::HTTP::Get.new url
|
75
|
+
http.request request do |response|
|
76
|
+
response.read_body(&block)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def get(url)
|
82
|
+
open("http://127.0.0.1:#{port}#{url}").read
|
83
|
+
end
|
84
|
+
|
85
|
+
def log
|
86
|
+
@log ||= ""
|
87
|
+
loop { @log << @pipe.read_nonblock(1) }
|
88
|
+
rescue Exception
|
89
|
+
@log
|
90
|
+
end
|
91
|
+
|
92
|
+
def installed?
|
93
|
+
return @installed unless @installed.nil?
|
94
|
+
require server
|
95
|
+
@installed = true
|
96
|
+
rescue LoadError
|
97
|
+
warn "#{server} is not installed, skipping integration tests"
|
98
|
+
@installed = false
|
99
|
+
end
|
100
|
+
|
101
|
+
def command
|
102
|
+
@command ||= begin
|
103
|
+
cmd = ["RACK_ENV=#{environment}", "exec"]
|
104
|
+
if RbConfig.respond_to? :ruby
|
105
|
+
cmd << RbConfig.ruby.inspect
|
106
|
+
else
|
107
|
+
file, dir = RbConfig::CONFIG.values_at('ruby_install_name', 'bindir')
|
108
|
+
cmd << File.expand_path(file, dir).inspect
|
109
|
+
end
|
110
|
+
cmd << "-I" << File.expand_path('../../lib', __FILE__).inspect
|
111
|
+
cmd << app_file.inspect << '-s' << server << '-o' << '127.0.0.1' << '-p' << port
|
112
|
+
cmd << "-e" << environment.to_s << '2>&1'
|
113
|
+
cmd.join " "
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def kill
|
118
|
+
return unless pipe
|
119
|
+
Process.kill("KILL", pipe.pid)
|
120
|
+
rescue NotImplementedError
|
121
|
+
system "kill -9 #{pipe.pid}"
|
122
|
+
rescue Errno::ESRCH
|
123
|
+
end
|
124
|
+
|
125
|
+
def webrick?
|
126
|
+
name.to_s == "webrick"
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if RUBY_ENGINE == "jruby"
|
131
|
+
class JRubyServer < BaseServer
|
132
|
+
def start_vm
|
133
|
+
require 'java'
|
134
|
+
# Create a new container, set load paths and env
|
135
|
+
# SINGLETHREAD means create a new runtime
|
136
|
+
vm = org.jruby.embed.ScriptingContainer.new(org.jruby.embed.LocalContextScope::SINGLETHREAD)
|
137
|
+
vm.load_paths = [File.expand_path('../../lib', __FILE__)]
|
138
|
+
vm.environment = ENV.merge('RACK_ENV' => environment.to_s)
|
139
|
+
|
140
|
+
# This ensures processing of RUBYOPT which activates Bundler
|
141
|
+
vm.provider.ruby_instance_config.process_arguments []
|
142
|
+
vm.argv = ['-s', server.to_s, '-o', '127.0.0.1', '-p', port.to_s, '-e', environment.to_s]
|
143
|
+
|
144
|
+
# Set stdout/stderr so we can retrieve log
|
145
|
+
@pipe = java.io.ByteArrayOutputStream.new
|
146
|
+
vm.output = java.io.PrintStream.new(@pipe)
|
147
|
+
vm.error = java.io.PrintStream.new(@pipe)
|
148
|
+
|
149
|
+
Thread.new do
|
150
|
+
# Hack to ensure that Kernel#caller has the same info as
|
151
|
+
# when run from command-line, for Sintra::Application.app_file.
|
152
|
+
# Also, line numbers are zero-based in JRuby's parser
|
153
|
+
vm.provider.runtime.current_context.set_file_and_line(app_file, 0)
|
154
|
+
# Run the app
|
155
|
+
vm.run_scriptlet org.jruby.embed.PathType::ABSOLUTE, app_file
|
156
|
+
# terminate launches at_exit hooks which start server
|
157
|
+
vm.terminate
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def run
|
162
|
+
return unless installed?
|
163
|
+
kill
|
164
|
+
@thread = start_vm
|
165
|
+
@started = Time.now
|
166
|
+
warn "#{server} up and running on port #{port}" if ping
|
167
|
+
at_exit { kill }
|
168
|
+
end
|
169
|
+
|
170
|
+
def log
|
171
|
+
String.from_java_bytes @pipe.to_byte_array
|
172
|
+
end
|
173
|
+
|
174
|
+
def kill
|
175
|
+
@thread.kill if @thread
|
176
|
+
@thread = nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
Server = JRubyServer
|
180
|
+
else
|
181
|
+
Server = BaseServer
|
182
|
+
end
|
183
|
+
|
184
|
+
def it(message, &block)
|
185
|
+
Server.each do |server|
|
186
|
+
next unless server.installed?
|
187
|
+
super "with #{server.name}: #{message}" do
|
188
|
+
self.server = server
|
189
|
+
server.run unless server.alive?
|
190
|
+
begin
|
191
|
+
instance_eval(&block)
|
192
|
+
rescue Exception => error
|
193
|
+
server.kill
|
194
|
+
raise error
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def self.extend_object(obj)
|
201
|
+
super
|
202
|
+
|
203
|
+
base_port = 5000 + Process.pid % 100
|
204
|
+
Sinatra::Base.server.each_with_index do |server, index|
|
205
|
+
Server.run(server, 5000+index)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
require File.expand_path('../integration_helper', __FILE__)
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
# These tests start a real server and talk to it over TCP.
|
6
|
+
# Every test runs with every detected server.
|
7
|
+
#
|
8
|
+
# See test/integration/app.rb for the code of the app we test against.
|
9
|
+
class IntegrationTest < Test::Unit::TestCase
|
10
|
+
extend IntegrationHelper
|
11
|
+
attr_accessor :server
|
12
|
+
|
13
|
+
it('sets the app_file') { assert_equal server.app_file, server.get("/app_file") }
|
14
|
+
it('only extends main') { assert_equal "true", server.get("/mainonly") }
|
15
|
+
|
16
|
+
it 'logs once in development mode' do
|
17
|
+
random = "%064x" % Kernel.rand(2**256-1)
|
18
|
+
server.get "/ping?x=#{random}"
|
19
|
+
count = server.log.scan("GET /ping?x=#{random}").count
|
20
|
+
server.webrick? ? assert(count > 0) : assert_equal(1, count)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'streams' do
|
24
|
+
next if server.webrick?
|
25
|
+
times, chunks = [Time.now], []
|
26
|
+
server.get_stream do |chunk|
|
27
|
+
next if chunk.empty?
|
28
|
+
chunks << chunk
|
29
|
+
times << Time.now
|
30
|
+
end
|
31
|
+
assert_equal ["a", "b"], chunks
|
32
|
+
assert times[1] - times[0] < 1
|
33
|
+
assert times[2] - times[1] > 1
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'streams async' do
|
37
|
+
next unless server.name == 'thin'
|
38
|
+
|
39
|
+
Timeout.timeout(3) do
|
40
|
+
chunks = []
|
41
|
+
server.get_stream '/async' do |chunk|
|
42
|
+
next if chunk.empty?
|
43
|
+
chunks << chunk
|
44
|
+
case chunk
|
45
|
+
when "hi!" then server.get "/send?msg=hello"
|
46
|
+
when "hello" then server.get "/send?close=1"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
assert_equal ['hi!', 'hello'], chunks
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'streams async from subclass' do
|
55
|
+
next unless server.name == 'thin'
|
56
|
+
|
57
|
+
Timeout.timeout(3) do
|
58
|
+
chunks = []
|
59
|
+
server.get_stream '/subclass/async' do |chunk|
|
60
|
+
next if chunk.empty?
|
61
|
+
chunks << chunk
|
62
|
+
case chunk
|
63
|
+
when "hi!" then server.get "/subclass/send?msg=hello"
|
64
|
+
when "hello" then server.get "/subclass/send?close=1"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_equal ['hi!', 'hello'], chunks
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
it 'starts the correct server' do
|
74
|
+
exp = %r{
|
75
|
+
==\sSinatra/#{Sinatra::VERSION}\s
|
76
|
+
has\staken\sthe\sstage\son\s\d+\sfor\sdevelopment\s
|
77
|
+
with\sbackup\sfrom\s#{server}
|
78
|
+
}ix
|
79
|
+
|
80
|
+
assert_match exp, server.log
|
81
|
+
end
|
82
|
+
end
|
data/test/less_test.rb
CHANGED
@@ -1,31 +1,57 @@
|
|
1
|
-
require File.
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
begin
|
2
4
|
require 'less'
|
3
5
|
|
4
6
|
class LessTest < Test::Unit::TestCase
|
5
|
-
def less_app(&block)
|
7
|
+
def less_app(options = {}, &block)
|
6
8
|
mock_app {
|
7
9
|
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
set options
|
8
11
|
get '/', &block
|
9
12
|
}
|
10
13
|
get '/'
|
11
14
|
end
|
12
15
|
|
13
16
|
it 'renders inline Less strings' do
|
14
|
-
less_app { less "@white_color: #fff; #main { background-color: @white_color }"}
|
17
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
18
|
+
assert ok?
|
19
|
+
assert_equal "#main{background-color:#ffffff;}", body.gsub(/\s/, "")
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'defaults content type to css' do
|
23
|
+
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
24
|
+
assert ok?
|
25
|
+
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'defaults allows setting content type per route' do
|
29
|
+
less_app do
|
30
|
+
content_type :html
|
31
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
32
|
+
end
|
33
|
+
assert ok?
|
34
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'defaults allows setting content type globally' do
|
38
|
+
less_app(:less => { :content_type => 'html' }) do
|
39
|
+
less "@white_color: #fff; #main { background-color: @white_color }"
|
40
|
+
end
|
15
41
|
assert ok?
|
16
|
-
assert_equal "
|
42
|
+
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
17
43
|
end
|
18
44
|
|
19
45
|
it 'renders .less files in views path' do
|
20
46
|
less_app { less :hello }
|
21
47
|
assert ok?
|
22
|
-
assert_equal "#main
|
48
|
+
assert_equal "#main{background-color:#ffffff;}", body.gsub(/\s/, "")
|
23
49
|
end
|
24
50
|
|
25
51
|
it 'ignores the layout option' do
|
26
52
|
less_app { less :hello, :layout => :layout2 }
|
27
53
|
assert ok?
|
28
|
-
assert_equal "#main
|
54
|
+
assert_equal "#main{background-color:#ffffff;}", body.gsub(/\s/, "")
|
29
55
|
end
|
30
56
|
|
31
57
|
it "raises error if template not found" do
|
@@ -35,3 +61,7 @@ class LessTest < Test::Unit::TestCase
|
|
35
61
|
assert_raise(Errno::ENOENT) { get('/') }
|
36
62
|
end
|
37
63
|
end
|
64
|
+
|
65
|
+
rescue LoadError
|
66
|
+
warn "#{$!.to_s}: skipping less tests"
|
67
|
+
end
|
data/test/liquid_test.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('../helper', __FILE__)
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'liquid'
|
5
|
+
|
6
|
+
class LiquidTest < Test::Unit::TestCase
|
7
|
+
def liquid_app(&block)
|
8
|
+
mock_app do
|
9
|
+
set :views, File.dirname(__FILE__) + '/views'
|
10
|
+
get '/', &block
|
11
|
+
end
|
12
|
+
get '/'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'renders inline liquid strings' do
|
16
|
+
liquid_app { liquid '<h1>Hiya</h1>' }
|
17
|
+
assert ok?
|
18
|
+
assert_equal "<h1>Hiya</h1>", body
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'renders .liquid files in views path' do
|
22
|
+
liquid_app { liquid :hello }
|
23
|
+
assert ok?
|
24
|
+
assert_equal "<h1>Hello From Liquid</h1>\n", body
|
25
|
+
end
|
26
|
+
|
27
|
+
it "renders with inline layouts" do
|
28
|
+
mock_app do
|
29
|
+
layout { "<h1>THIS. IS. {{ yield }}</h1>" }
|
30
|
+
get('/') { liquid '<EM>SPARTA</EM>' }
|
31
|
+
end
|
32
|
+
get '/'
|
33
|
+
assert ok?
|
34
|
+
assert_equal "<h1>THIS. IS. <EM>SPARTA</EM></h1>", body
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders with file layouts" do
|
38
|
+
liquid_app { liquid 'Hello World', :layout => :layout2 }
|
39
|
+
assert ok?
|
40
|
+
assert_equal "<h1>Liquid Layout!</h1>\n<p>Hello World</p>\n", body
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises error if template not found" do
|
44
|
+
mock_app { get('/') { liquid :no_such_template } }
|
45
|
+
assert_raise(Errno::ENOENT) { get('/') }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "allows passing locals" do
|
49
|
+
liquid_app do
|
50
|
+
liquid '{{ value }}', :locals => { :value => 'foo' }
|
51
|
+
end
|
52
|
+
assert ok?
|
53
|
+
assert_equal 'foo', body
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
rescue LoadError
|
58
|
+
warn "#{$!.to_s}: skipping liquid tests"
|
59
|
+
end
|