summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-02-03 00:01:56 +0100
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2020-02-03 12:12:41 +1300
commite3fd0c4e23608a27e7e8a1bcddb8cf59238ae0d8 (patch)
tree3fc8a5f6d9f24e21552566b3b2faa6ee555c967c
parentf2d2df4016a906beec755b63b4edfcc07b58ee05 (diff)
downloadrack-e3fd0c4e23608a27e7e8a1bcddb8cf59238ae0d8.tar.gz
Support magic comments in .ru files
* Such as # frozen_string_literal: true.
-rw-r--r--lib/rack/builder.rb7
-rw-r--r--test/builder/frozen.ru7
-rw-r--r--test/spec_builder.rb9
3 files changed, 21 insertions, 2 deletions
diff --git a/lib/rack/builder.rb b/lib/rack/builder.rb
index c9c45048..764e3f1f 100644
--- a/lib/rack/builder.rb
+++ b/lib/rack/builder.rb
@@ -109,8 +109,11 @@ module Rack
# Evaluate the given +builder_script+ string in the context of
# a Rack::Builder block, returning a Rack application.
def self.new_from_string(builder_script, file = "(rackup)")
- eval "Rack::Builder.new {\n" + builder_script + "\n}.to_app",
- TOPLEVEL_BINDING, file, 0
+ # We want to build a variant of TOPLEVEL_BINDING with self as a Rack::Builder instance.
+ # We cannot use instance_eval(String) as that would resolve constants differently.
+ binding, builder = TOPLEVEL_BINDING.eval('Rack::Builder.new.instance_eval { [binding, self] }')
+ eval builder_script, binding, file
+ builder.to_app
end
# Initialize a new Rack::Builder instance. +default_app+ specifies the
diff --git a/test/builder/frozen.ru b/test/builder/frozen.ru
new file mode 100644
index 00000000..5bad750f
--- /dev/null
+++ b/test/builder/frozen.ru
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+run lambda { |env|
+ body = 'frozen'
+ raise "Not frozen!" unless body.frozen?
+ [200, { 'Content-Type' => 'text/plain' }, [body]]
+}
diff --git a/test/spec_builder.rb b/test/spec_builder.rb
index 424e3314..c0f59c18 100644
--- a/test/spec_builder.rb
+++ b/test/spec_builder.rb
@@ -270,6 +270,15 @@ describe Rack::Builder do
Encoding.default_external = enc
end
end
+
+ it "respects the frozen_string_literal magic comment" do
+ app, _ = Rack::Builder.parse_file(config_file('frozen.ru'))
+ response = Rack::MockRequest.new(app).get('/')
+ response.body.must_equal 'frozen'
+ body = response.instance_variable_get(:@body)
+ body.must_equal(['frozen'])
+ body[0].frozen?.must_equal true
+ end
end
describe 'new_from_string' do