import sinatra-decompile
This commit is contained in:
parent
07a649ab6d
commit
f5e015894d
|
@ -0,0 +1,61 @@
|
|||
require 'sinatra/base'
|
||||
require 'backports'
|
||||
|
||||
module Sinatra
|
||||
##
|
||||
# Can be used as extension or stand-alone:
|
||||
#
|
||||
# Sinatra::Decompile.decompile(...)
|
||||
module Decompile
|
||||
extend self
|
||||
|
||||
##
|
||||
# Regenerates a string pattern for a given route
|
||||
#
|
||||
# Example:
|
||||
#
|
||||
# class Sinatra::Application
|
||||
# routes.each do |verb, list|
|
||||
# puts "#{verb}:"
|
||||
# list.each do |data|
|
||||
# puts "\t" << decompile(data)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# Will return the internal Regexp if unable to reconstruct the pattern,
|
||||
# which likely indicates that a Regexp was used in the first place.
|
||||
#
|
||||
# You can also use this to check whether you could actually use a string
|
||||
# pattern instead of your regexp:
|
||||
#
|
||||
# decompile /^/foo$/ # => '/foo'
|
||||
def decompile(pattern, keys = nil, *)
|
||||
# Everything in here is basically just the reverse of
|
||||
# Sinatra::Base#compile
|
||||
pattern, keys = pattern if pattern.respond_to? :to_ary
|
||||
keys, str = keys.try(:dup), pattern.inspect
|
||||
return pattern unless str.start_with? '/' and str.end_with? '/'
|
||||
str.gsub! /^\/\^?|\$?\/$/, ''
|
||||
return pattern if str =~ /^[\.\+]/
|
||||
str.gsub! /\([^\(]*\)/ do |part|
|
||||
case part
|
||||
when '(.*?)'
|
||||
return pattern if keys.shift != 'splat'
|
||||
'*'
|
||||
when '([^\/?#]+)'
|
||||
return pattern if keys.empty?
|
||||
":" << keys.shift
|
||||
else
|
||||
return pattern
|
||||
end
|
||||
end
|
||||
str.gsub /(.)([\.\+\(\)\/])/ do
|
||||
return pattern if $1 != "\\"
|
||||
$2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
register Decompile
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
require 'backports'
|
||||
require_relative 'spec_helper'
|
||||
|
||||
RSpec::Matchers.define :decompile do |path|
|
||||
match do |app|
|
||||
@compiled, @keys = app.send :compile, path
|
||||
@decompiled = app.decompile(@compiled, @keys)
|
||||
@decompiled.should == path
|
||||
end
|
||||
|
||||
failure_message_for_should do |app|
|
||||
values = [app, @compiled, @keys, path, @decompiled].map(&:inspect)
|
||||
"expected %s to decompile %s with %s to %s, but was %s" % values
|
||||
end
|
||||
end
|
||||
|
||||
describe Sinatra::Decompile do
|
||||
subject { Sinatra::Application }
|
||||
it { should decompile("") }
|
||||
it { should decompile("/") }
|
||||
it { should decompile("/?") }
|
||||
it { should decompile("/foo") }
|
||||
it { should decompile("/:name") }
|
||||
it { should decompile("/:name?") }
|
||||
it { should decompile("/:foo/:bar") }
|
||||
it { should decompile("/page/:id/edit") }
|
||||
it { should decompile("/hello/*") }
|
||||
it { should decompile("/*/foo/*") }
|
||||
it { should decompile("*") }
|
||||
it { should decompile(":name.:format") }
|
||||
it { should decompile(/./) }
|
||||
it { should decompile(/f(oo)/) }
|
||||
it { should decompile(/ba+r/) }
|
||||
|
||||
it 'just returns strings' do
|
||||
subject.decompile('/foo').should == '/foo'
|
||||
end
|
||||
|
||||
it 'just decompile simple regexps without keys' do
|
||||
subject.decompile(%r{/foo}).should == '/foo'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
require 'forwardable'
|
||||
|
||||
module TestHelpers
|
||||
end
|
||||
|
||||
require 'sinatra/contrib'
|
||||
|
||||
RSpec.configure do |config|
|
||||
config.expect_with :rspec, :stdlib
|
||||
config.include Sinatra::TestHelpers
|
||||
end
|
Loading…
Reference in New Issue