diff options
author | Benoit Daloze <eregontp@gmail.com> | 2020-02-03 00:01:56 +0100 |
---|---|---|
committer | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2020-02-03 12:12:41 +1300 |
commit | e3fd0c4e23608a27e7e8a1bcddb8cf59238ae0d8 (patch) | |
tree | 3fc8a5f6d9f24e21552566b3b2faa6ee555c967c | |
parent | f2d2df4016a906beec755b63b4edfcc07b58ee05 (diff) | |
download | rack-e3fd0c4e23608a27e7e8a1bcddb8cf59238ae0d8.tar.gz |
Support magic comments in .ru files
* Such as # frozen_string_literal: true.
-rw-r--r-- | lib/rack/builder.rb | 7 | ||||
-rw-r--r-- | test/builder/frozen.ru | 7 | ||||
-rw-r--r-- | test/spec_builder.rb | 9 |
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 |