From e53fb2bcad76fe6e20c54f117e4e6e807e4ab50a Mon Sep 17 00:00:00 2001 From: Blake Mizerany Date: Wed, 21 Nov 2007 01:47:29 -0800 Subject: [PATCH] starting again --- CHANGELOG | 8 - LICENSE | 22 --- Manifest | 52 ------- README | 119 --------------- RakeFile | 35 ----- examples/hello/hello.rb | 26 ---- examples/hello/views/hello.erb | 1 - files/default_index.erb | 42 ----- files/error.erb | 9 -- files/logo.png | Bin 26576 -> 0 bytes files/not_found.erb | 52 ------- lib/sinatra.rb | 105 +++++++------ lib/sinatra/context.rb | 94 ------------ lib/sinatra/context/renderer.rb | 75 --------- lib/sinatra/core_ext/array.rb | 5 - lib/sinatra/core_ext/class.rb | 49 ------ lib/sinatra/core_ext/hash.rb | 7 - lib/sinatra/core_ext/kernel.rb | 16 -- lib/sinatra/core_ext/metaid.rb | 18 --- lib/sinatra/core_ext/module.rb | 11 -- lib/sinatra/core_ext/symbol.rb | 5 - lib/sinatra/dispatcher.rb | 23 --- lib/sinatra/dsl.rb | 169 --------------------- lib/sinatra/environment.rb | 19 --- lib/sinatra/event.rb | 244 ------------------------------ lib/sinatra/irb.rb | 56 ------- lib/sinatra/loader.rb | 31 ---- lib/sinatra/logger.rb | 22 --- lib/sinatra/options.rb | 49 ------ lib/sinatra/rack_ext/request.rb | 15 -- lib/sinatra/route.rb | 65 -------- lib/sinatra/server.rb | 57 ------- lib/sinatra/test/methods.rb | 62 -------- lib/sinatra/test/spec.rb | 39 ----- lib/sinatra2.rb | 65 -------- site/index.htm | 104 ------------- site/index.html | 104 ------------- site/logo.png | Bin 26576 -> 0 bytes test/helper.rb | 2 - test/sinatra/dispatcher_test.rb | 87 ----------- test/sinatra/event_test.rb | 44 ------ test/sinatra/filter_test.rb | 19 --- test/sinatra/haml_test.rb | 21 --- test/sinatra/renderer_test.rb | 46 ------ test/sinatra/request_test.rb | 21 --- test/sinatra/route_test.rb | 21 --- test/sinatra/static_files/foo.txt | 1 - test/sinatra/static_files_test.rb | 44 ------ test/sinatra/url_test.rb | 16 -- vendor/erb/init.rb | 3 - vendor/erb/lib/erb.rb | 41 ----- vendor/haml/init.rb | 3 - vendor/haml/lib/haml.rb | 41 ----- 53 files changed, 60 insertions(+), 2225 deletions(-) delete mode 100644 CHANGELOG delete mode 100644 LICENSE delete mode 100644 Manifest delete mode 100644 README delete mode 100644 RakeFile delete mode 100644 examples/hello/hello.rb delete mode 100644 examples/hello/views/hello.erb delete mode 100644 files/default_index.erb delete mode 100644 files/error.erb delete mode 100644 files/logo.png delete mode 100644 files/not_found.erb delete mode 100644 lib/sinatra/context.rb delete mode 100644 lib/sinatra/context/renderer.rb delete mode 100644 lib/sinatra/core_ext/array.rb delete mode 100644 lib/sinatra/core_ext/class.rb delete mode 100644 lib/sinatra/core_ext/hash.rb delete mode 100644 lib/sinatra/core_ext/kernel.rb delete mode 100644 lib/sinatra/core_ext/metaid.rb delete mode 100644 lib/sinatra/core_ext/module.rb delete mode 100644 lib/sinatra/core_ext/symbol.rb delete mode 100644 lib/sinatra/dispatcher.rb delete mode 100644 lib/sinatra/dsl.rb delete mode 100644 lib/sinatra/environment.rb delete mode 100644 lib/sinatra/event.rb delete mode 100644 lib/sinatra/irb.rb delete mode 100644 lib/sinatra/loader.rb delete mode 100644 lib/sinatra/logger.rb delete mode 100644 lib/sinatra/options.rb delete mode 100644 lib/sinatra/rack_ext/request.rb delete mode 100644 lib/sinatra/route.rb delete mode 100644 lib/sinatra/server.rb delete mode 100644 lib/sinatra/test/methods.rb delete mode 100644 lib/sinatra/test/spec.rb delete mode 100644 lib/sinatra2.rb delete mode 100644 site/index.htm delete mode 100644 site/index.html delete mode 100644 site/logo.png delete mode 100644 test/helper.rb delete mode 100644 test/sinatra/dispatcher_test.rb delete mode 100644 test/sinatra/event_test.rb delete mode 100644 test/sinatra/filter_test.rb delete mode 100644 test/sinatra/haml_test.rb delete mode 100644 test/sinatra/renderer_test.rb delete mode 100644 test/sinatra/request_test.rb delete mode 100644 test/sinatra/route_test.rb delete mode 100644 test/sinatra/static_files/foo.txt delete mode 100644 test/sinatra/static_files_test.rb delete mode 100644 test/sinatra/url_test.rb delete mode 100644 vendor/erb/init.rb delete mode 100644 vendor/erb/lib/erb.rb delete mode 100644 vendor/haml/init.rb delete mode 100644 vendor/haml/lib/haml.rb diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 0eea2236..00000000 --- a/CHANGELOG +++ /dev/null @@ -1,8 +0,0 @@ -v0.1.7 FIXES: - -* test/development/production helpers changed to config_for. There was a problem with "test" fubar'ing libraries such as the new release of Sequel -* StaticEvent now makes sure the file it's looking for is really a file. - -v0.1.6 Additions: require users vendor directory on load -v0.1.5 Mutex and before-filters -v0.1.0 Released! diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 882fce76..00000000 --- a/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2007 Blake Mizerany - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/Manifest b/Manifest deleted file mode 100644 index 65ae26f7..00000000 --- a/Manifest +++ /dev/null @@ -1,52 +0,0 @@ -CHANGELOG -examples/hello/hello.rb -examples/hello/views/hello.erb -examples/todo/todo.rb -files/default_index.erb -files/error.erb -files/logo.png -files/not_found.erb -lib/sinatra/context/renderer.rb -lib/sinatra/context.rb -lib/sinatra/core_ext/array.rb -lib/sinatra/core_ext/class.rb -lib/sinatra/core_ext/hash.rb -lib/sinatra/core_ext/kernel.rb -lib/sinatra/core_ext/metaid.rb -lib/sinatra/core_ext/module.rb -lib/sinatra/core_ext/symbol.rb -lib/sinatra/dispatcher.rb -lib/sinatra/dsl.rb -lib/sinatra/environment.rb -lib/sinatra/event.rb -lib/sinatra/irb.rb -lib/sinatra/loader.rb -lib/sinatra/logger.rb -lib/sinatra/options.rb -lib/sinatra/rack_ext/request.rb -lib/sinatra/route.rb -lib/sinatra/server.rb -lib/sinatra/sessions.rb -lib/sinatra/test_methods.rb -lib/sinatra.rb -LICENSE -Manifest -RakeFile -README -site/index.htm -site/index.html -site/logo.png -test/helper.rb -test/sinatra/dispatcher_test.rb -test/sinatra/event_test.rb -test/sinatra/renderer_test.rb -test/sinatra/request_test.rb -test/sinatra/route_test.rb -test/sinatra/static_files/foo.txt -test/sinatra/static_files_test.rb -test/sinatra/url_test.rb -vendor/erb/init.rb -vendor/erb/lib/erb.rb -vendor/haml/init.rb -vendor/haml/lib/haml.rb -Rakefile diff --git a/README b/README deleted file mode 100644 index 50be282e..00000000 --- a/README +++ /dev/null @@ -1,119 +0,0 @@ -Sinatra (C) 2007 By Blake Mizerany - -= Classy web-development dressed in a DSL - -== Install! - - sudo gem install sinatra -y - -== Use! - -I'm going to move quick. I'll let you drool at your own pace. - -* Create a file called lyrics.rb (or any name you like) - -* Add - require 'rubygems' - require 'sinatra' - -* Run (yes, with just ruby) - % ruby lyrics.rb - == Sinata has taken the stage on port 4567! - -* Take a moment and view the default page http://localhost:4567. Go ahead and bask in it's glory. - -* Notice: - * It didn't create any page to show you that default page (just a cool thing to see, that's all) - * There was nothing generated other than a log file - * Sinatra is a really cool name for a web-framework that's a DSL - -* Modify lyrics.rb by adding: - get '/' do - 'Hello World' - end - -* Refresh (no need to restart Sinatra): - http://localhost:4567 - -* Modify again (then refresh) -- And yes, this presentation logic can be quickly extracted to a template.. see below. - get '/' do - <<-HTML -
- - -
- HTML - end - - post '/' do - "Hello #{params[:name] || 'World'}!" - end - -* Test (lyrics_test.rb) -- We should be doing this first... for the purposes of this tutorial, we're doing it here - - require 'sinatra/test/spec' - require 'lyrics' - - context "My app" do - specify "should have a form" do - get_it '/' - response.should.be.ok - body.scan('form').size.should.equal 1 - - post_it '/', :name => 'Sinatra' - response.should.be.ok - body.should.equal 'Hello Sinatra!' - end - end - -For more test helpers see: Sinatra::Test::Methods and http://rack.rubyforge.org/doc/classes/Rack/Response/Helpers.html - -* Now you try: - Use the Sinatra::Erb::EventContext or Sinatra::Haml::EventContext to do the same. Do them inline and as template files. - -* Learn more cool stuff: - see Sinatra::Dsl - -* Create your own plugins! - 1. Create a 'vendor' directory in your app directory - 2. Lay it out like: - - myapp.rb : root - |- vendor - | - plugin_name - | - init.rb # load and hook here - | - lib - |- modules/classes here - - 3. Use it in your app! - - see $SINATRA_GEM_ROOT/vendor/erb or $SINATRA_GEM_ROOT/vendor/erb for examples. - -* Tell! -We would love to here what you're doing with Sinatra and any cool patches/features you would like. (blake { dot } mizerany [ at ] gmail) - -* Talk! -IRC (irc.freenode.com #sinatra) -Mailing List (sinatrarb@googlegroups.com) - -* Contribute - -We're using git as our scm.. cuz.. it rocks. You can get the latest source from http://repo.or.cz/w/sinatra.git - -NOTE: You can also get tar'd snapshots of each commit there too. So technically you don't need git to get the latest code. - -It's probably going to happen.. you'll find a bug. Please help by: - -* Sending a message to sintrarb@googlegroups.com with BUG: at the start of the subject (I'm working on a better tracking system) -* Please send patches or pull requests to (blake { dot } mizerany [ at ] gmail) don't forget the dot com. ;) - -== Thanks! - -- Ezra Zygmuntowicz (http://brainspl.at) for answering all those random questions over IM and all the poached code -- Ditto to Chris Wanstrath (errtheblog.com) and helping me keep things simple, and some cool tricks -- Ari Lerner over at CitrusByte for ideas, code, and enthusiasm -- Christian Neukirchen for Rack (http://rack.rubyforge.org/) -- Koshi (http://www.songbirdnest.com/jkoshi/blog) here at POTI, Inc. for the Sinatra mark -- Pete Golibersuch for the hat logo -- John Philip Green (http://www.linkedin.com/in/johngreen) for motivation and evangelism -- The team here at songbirdnest.com for cool ideas diff --git a/RakeFile b/RakeFile deleted file mode 100644 index a6fd419a..00000000 --- a/RakeFile +++ /dev/null @@ -1,35 +0,0 @@ -require 'rake/testtask' -require 'ftools' - -Version = '0.1.0' - -begin - require 'rubygems' - gem 'echoe' - ENV['RUBY_FLAGS'] = "" - require 'echoe' - - Echoe.new('sinatra') do |p| - p.rubyforge_name = 'sinatra' - p.dependencies = ['mongrel >=1.0.1', 'rack >=0.2.0'] - p.summary = "Sinatra is a classy web-framework dressed in a DSL" - p.description = "Sinatra is a classy web-framework dressed in a DSL" - p.url = "http://sinatra.rubyforge.org/" - p.author = 'Blake Mizerany' - p.email = "blake.mizerany@gmail.com" - p.test_pattern = 'test/**/*_test.rb' - p.include_rakefile = true - p.rdoc_pattern = ['README', 'LICENSE'] + Dir.glob('lib/**/*.rb') + Dir.glob('vendor/**/*.rb') + Dir.glob('lib/sinatra/test/*.rb') - p.docs_host = "bmizerany@rubyforge.org:/var/www/gforge-projects/" - end - -rescue LoadError -end - -desc 'Clear all the log files from here down' -task :remove_logs do - Dir.glob(Dir.pwd + '/**/*.log') do |logfile| - FileUtils.rm(logfile) - puts 'Removed: %s' % logfile - end -end diff --git a/examples/hello/hello.rb b/examples/hello/hello.rb deleted file mode 100644 index ca8417d8..00000000 --- a/examples/hello/hello.rb +++ /dev/null @@ -1,26 +0,0 @@ -$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib' -require 'sinatra' - -config_for(:production) do - - get 404 do - "Not sure what you're looking for .. try something else." - end -end - -get '/' do - "Hello World!" -end - -get '/erb.xml' do - header 'Content-Type' => 'application/xml' - '' -end - -get '/erb' do - erb :hello -end - -get '/erb2' do - erb 'Hello <%= params[:name].capitalize || "World" %> 2!' -end diff --git a/examples/hello/views/hello.erb b/examples/hello/views/hello.erb deleted file mode 100644 index 2df31aa8..00000000 --- a/examples/hello/views/hello.erb +++ /dev/null @@ -1 +0,0 @@ -Hello <%= params[:name].capitalize || 'World' %>! diff --git a/files/default_index.erb b/files/default_index.erb deleted file mode 100644 index 243dad20..00000000 --- a/files/default_index.erb +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - Sinatra has taken the stage! - - - - -
- -
-

Sing this diddy to move on:

-
-get "/" do
-  ... your code here ..
-end
-
-
- - \ No newline at end of file diff --git a/files/error.erb b/files/error.erb deleted file mode 100644 index 81f5a5a6..00000000 --- a/files/error.erb +++ /dev/null @@ -1,9 +0,0 @@ -

Error!

- -

-<%= @error.message %> -

- -
-<%= @error.backtrace.join('
') %> -
diff --git a/files/logo.png b/files/logo.png deleted file mode 100644 index a0d868a0405ea2321400aa909a15fcf71e7cff6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26576 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 - - - - - - Not Found :: Sinatra - - - - - - -
-
-
-

Sinatra doesn't know this diddy, but he's a quick study.

-

Sing this one:

-
<%= request.request_method.downcase %> '<%= request.path_info %>' do
-	html "Replace this with your code."
-end
-
-
-
- - - - \ No newline at end of file diff --git a/lib/sinatra.rb b/lib/sinatra.rb index 5722132d..af6e3c90 100644 --- a/lib/sinatra.rb +++ b/lib/sinatra.rb @@ -1,50 +1,65 @@ -# Copyright (c) 2007 Blake Mizerany -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. +require "rubygems" +require "rack" -%w(rubygems rack).each do |library| - begin - require library - rescue LoadError - raise "== Sinatra cannot run without #{library} installed" +class String + def to_param + URI.escape(self) + end + + def from_param + URI.unescape(self) end end -SINATRA_ROOT = File.dirname(__FILE__) + '/..' - -require File.dirname(__FILE__) + '/sinatra/loader' - -Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/lib/sinatra/core_ext/*.rb') -Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/lib/sinatra/rack_ext/*.rb') -Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/lib/sinatra/*.rb') - -Sinatra::Environment.prepare - -Sinatra::Loader.load_files Dir.glob(SINATRA_ROOT + '/vendor/*/init.rb') -Sinatra::Loader.load_files Dir.glob(File.dirname($0) + '/vendor/*/init.rb') - -at_exit do - raise $! if $! - Sinatra::Environment.prepare_loggers unless Sinatra::Environment.test? - Sinatra::Irb.start! if Sinatra::Options.console - Sinatra::Server.new.start unless Sinatra::Server.running +class Symbol + def to_proc + Proc.new { |*args| args.shift.__send__(self, *args) } + end end + +class Array + def to_hash + self.inject({}) { |h, (k, v)| h[k] = v; h } + end +end + +module Sinatra + extend self + + def request_types + @request_types ||= %w(GET PUT POST DELETE) + end + + def events + @events ||= Hash.new do |hash, key| + hash[key] = [] if request_types.include?(key) + end + end + + class Route + + URI_CHAR = '[^/?:,&#]'.freeze unless defined?(URI_CHAR) + PARAM = /:(#{URI_CHAR}+)/.freeze unless defined?(PARAM) + + def initialize(path, &b) + @path, @block = path, b + @param_keys = [] + regex = path.to_s.gsub(PARAM) do + @param_keys << $1.intern + "(#{URI_CHAR}+)" + end + @pattern = /^#{regex}$/ + @struct = Struct.new(:block, :params) + end + + def match(path) + return nil unless path =~ @pattern + params = @param_keys.zip($~.captures.map(&:from_param)).to_hash + @struct.new(@block, params) + end + + end + +end + + diff --git a/lib/sinatra/context.rb b/lib/sinatra/context.rb deleted file mode 100644 index b07ba0ad..00000000 --- a/lib/sinatra/context.rb +++ /dev/null @@ -1,94 +0,0 @@ -require File.dirname(__FILE__) + '/context/renderer' - -module Sinatra - - class EventContext - - cattr_accessor :logger - cattr_accessor :reraise_errors - attr_reader :request, :response - - include Sinatra::Renderer - - def initialize(request) #:nodoc: - @request = request - @response = Rack::Response.new - @response.body = nil - end - - # Sets or returns the status - def status(value = nil) - @response.status = value if value - @response.status || 200 - end - - # Sets or returns the body - # *Usage* - # body 'test' - # or - # body do - # 'test' - # end - # both are the same - # - def body(value = nil, &block) - @response.body = value if value - @response.body = block.call if block - @response.body - end - - # Renders an exception to +body+ and sets status to 500 - def error(value = nil) - raise value if value.kind_of?(Exception) && reraise_errors - if value - status 500 - @error = value - erb :error, :views_directory => SINATRA_ROOT + '/files/' - end - @error - end - - def set_cookie(key, value) - @response.set_cookie(key, value) - end - - def delete_cookie(key, value) - @response.delete_cookie(key, value) - end - - # Sets or returns response headers - # - # *Usage* - # header 'Content-Type' => 'text/html' - # header 'Foo' => 'Bar' - # or - # headers 'Content-Type' => 'text/html', - # 'Foo' => 'Bar' - # - # Whatever blows your hair back - def headers(value = nil) - @response.headers.merge!(value) if value - @response.headers - end - alias :header :headers - - # Returns a Hash of params. Keys are symbolized - def params - @params ||= @request.params.symbolize_keys - end - - # Redirect to a url - def redirect(path) - logger.info "Redirecting to: #{path}" - status 302 - header 'Location' => path - end - - def log_event #:nodoc: - logger.info "#{request.request_method} #{request.path_info} | Status: #{status} | Params: #{params.inspect}" - logger.exception(error) if error - end - - end - -end diff --git a/lib/sinatra/context/renderer.rb b/lib/sinatra/context/renderer.rb deleted file mode 100644 index 3ccfbc15..00000000 --- a/lib/sinatra/context/renderer.rb +++ /dev/null @@ -1,75 +0,0 @@ -module Sinatra - - # The magic or rendering happens here. This is included in Sinatra::EventContext on load. - # - # These methods are the foundation for Sinatra::Erb and Sinatra::Haml and allow you to quickly - # create custom wrappers for your favorite rendering engines outside of erb and haml. - - module Renderer - - Layouts = Hash.new # :nodoc: - - DEFAULT_OPTIONS = { - :views_directory => 'views', - :layout => :layout - } - - - # Renders templates from a string or file and handles their layouts: - # - # Example: - # module MyRenderer - # def my(template, options, &layout) - # render(template, :my, options, &layout) - # end - # - # def render_my(template) - # template.capitalize # It capitalizes templates!!!!! WOW! - # end - # end - # Sinatra::EventContext.send :include, MyRenderer - # - # get '/' do - # my "something" - # end - # - # get_it '/' # => 'Something' - # - # The second method is named render_extname. render will call this dynamicly - # - # paramaters: - # * +template+ If String, renders the string. If Symbol, reads from file with the basename of the Symbol; uses +renderer+ for extension. - # * +renderer+ A symbol defining the render_ method to call and the extension append to +template+ when looking in the +views_directory+ - # * +options+ An optional Hash of options (see next section) - # - # options: - # * +:views_directory+ Allows you to override the default 'views' directory an look for the template in another - # * +:layout+ Which layout to use (see Sinatra::Dsl). false to force a render with no layout. Defaults to :default layout - # - def render(template, renderer, options = {}) - options = DEFAULT_OPTIONS.merge(options) - - layout = block_given? ? yield : Layouts[options[:layout]] - - result_method = 'render_%s' % renderer - - if layout - send(result_method, layout) { send(result_method, determine_template(template, renderer, options)) } - else - send(result_method, determine_template(template, renderer, options)) - end - end - - protected - - def determine_template(template, ext, options) - if template.is_a?(Symbol) - File.read("%s/%s.%s" % [options[:views_directory], template, ext]) - else - template - end - end - - end - -end diff --git a/lib/sinatra/core_ext/array.rb b/lib/sinatra/core_ext/array.rb deleted file mode 100644 index 5ee1fc28..00000000 --- a/lib/sinatra/core_ext/array.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Array - def to_hash - self.inject({}) { |h, (k, v)| h[k] = v; h } - end -end diff --git a/lib/sinatra/core_ext/class.rb b/lib/sinatra/core_ext/class.rb deleted file mode 100644 index ccdae457..00000000 --- a/lib/sinatra/core_ext/class.rb +++ /dev/null @@ -1,49 +0,0 @@ -# Extends the class object with class and instance accessors for class attributes, -# just like the native attr* accessors for instance attributes. -class Class # :nodoc: - def cattr_reader(*syms) - syms.flatten.each do |sym| - next if sym.is_a?(Hash) - class_eval(<<-EOS, __FILE__, __LINE__) - unless defined? @@#{sym} - @@#{sym} = nil - end - - def self.#{sym} - @@#{sym} - end - - def #{sym} - @@#{sym} - end - EOS - end - end - - def cattr_writer(*syms) - options = syms.last.is_a?(Hash) ? syms.pop : {} - syms.flatten.each do |sym| - class_eval(<<-EOS, __FILE__, __LINE__) - unless defined? @@#{sym} - @@#{sym} = nil - end - - def self.#{sym}=(obj) - @@#{sym} = obj - end - - #{" - def #{sym}=(obj) - @@#{sym} = obj - end - " unless options[:instance_writer] == false } - EOS - end - end - - def cattr_accessor(*syms) - cattr_reader(*syms) - cattr_writer(*syms) - end - -end diff --git a/lib/sinatra/core_ext/hash.rb b/lib/sinatra/core_ext/hash.rb deleted file mode 100644 index e7104407..00000000 --- a/lib/sinatra/core_ext/hash.rb +++ /dev/null @@ -1,7 +0,0 @@ -class Hash - - def symbolize_keys - self.inject({}) { |h,(k,v)| h[k.to_sym] = v; h } - end - -end diff --git a/lib/sinatra/core_ext/kernel.rb b/lib/sinatra/core_ext/kernel.rb deleted file mode 100644 index e8b7a43e..00000000 --- a/lib/sinatra/core_ext/kernel.rb +++ /dev/null @@ -1,16 +0,0 @@ -module Kernel - # (Taken from ActiveSupport) - # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards. - # - # silence_warnings do - # value = noisy_call # no warning voiced - # end - # - # noisy_call # warning voiced - def silence_warnings - old_verbose, $VERBOSE = $VERBOSE, nil - yield - ensure - $VERBOSE = old_verbose - end -end diff --git a/lib/sinatra/core_ext/metaid.rb b/lib/sinatra/core_ext/metaid.rb deleted file mode 100644 index 415ca17a..00000000 --- a/lib/sinatra/core_ext/metaid.rb +++ /dev/null @@ -1,18 +0,0 @@ -# Compliments to why for this: -# http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html - -class Object - # The hidden singleton lurks behind everyone - def metaclass; class << self; self; end; end - def meta_eval &blk; metaclass.instance_eval &blk; end - - # Adds methods to a metaclass - def meta_def name, &blk - meta_eval { define_method name, &blk } - end - - # Defines an instance method within a class - def class_def name, &blk - class_eval { define_method name, &blk } - end -end diff --git a/lib/sinatra/core_ext/module.rb b/lib/sinatra/core_ext/module.rb deleted file mode 100644 index 23383737..00000000 --- a/lib/sinatra/core_ext/module.rb +++ /dev/null @@ -1,11 +0,0 @@ -class Module - def attr_with_default(sym, default) - define_method "#{sym}=" do |obj| - instance_variable_set("@#{sym}", obj) - end - - define_method sym do - instance_variable_get("@#{sym}") || default - end - end -end diff --git a/lib/sinatra/core_ext/symbol.rb b/lib/sinatra/core_ext/symbol.rb deleted file mode 100644 index b71f7f05..00000000 --- a/lib/sinatra/core_ext/symbol.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Symbol - def to_proc - Proc.new { |*args| args.shift.__send__(self, *args) } - end -end diff --git a/lib/sinatra/dispatcher.rb b/lib/sinatra/dispatcher.rb deleted file mode 100644 index aedee46a..00000000 --- a/lib/sinatra/dispatcher.rb +++ /dev/null @@ -1,23 +0,0 @@ -module Sinatra - - class Dispatcher - - cattr_accessor :logger - - def call(env) - Loader.reload! if Options.environment == :development - - @request = Rack::Request.new(env) - - event = EventManager.determine_event( - @request.request_method.downcase.intern, - @request.path_info - ) - - result = event.attend(@request) - result.response.to_a - end - - end - -end diff --git a/lib/sinatra/dsl.rb b/lib/sinatra/dsl.rb deleted file mode 100644 index 201bf29a..00000000 --- a/lib/sinatra/dsl.rb +++ /dev/null @@ -1,169 +0,0 @@ - -module Sinatra - - module Dsl - - # Define an Event that responds to a +path+ on GET method - # - # The +path+ can be a template (i.e. '/:foo/bar/:baz'). When recognized, it will add :foo and :baz to +params+ with their values. - # - # Example: - # # Going RESTful - # - # get '/' do - # .. show stuff .. - # end - # - # post '/' do - # .. add stuff .. - # redirect '/' - # end - # - # put '/:id' do - # .. update params[:id] .. - # redirect '/' - # end - # - # delete '/:id' do - # .. delete params[:id] .. - # redirect '/' - # end - # - # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a _method param whose value is PUT or DELETE - # - def get(path, &block) - Sinatra::Event.new(:get, path, &block) - end - - # Same as get but responds to POST - def post(path, &block) - Sinatra::Event.new(:post, path, &block) - end - - # Same as get but responds to PUT - # - # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a _method param whose value is PUT or DELETE - def put(path, &block) - Sinatra::Event.new(:put, path, &block) - end - - # Same as get but responds to DELETE - # - # BIG NOTE: PUT and DELETE are trigged when POSTing to their paths with a _method param whose value is PUT or DELETE - def delete(path, &block) - Sinatra::Event.new(:delete, path, &block) - end - - # Run given block after each Event's execution - # Usage: - # before_attend do - # logger.debug "After event attend!" - # end - # or - # before_attend :authorize # authorize is a helper method defined using helpers - # - # Stop execution using - throw :halt - # before_attend do - # throw :halt, 401 unless has_access? - # end - # Throw a Symbol to execute a helper method - # Throw a String to render it as the content - # Throw a Fixnum to set the status - # - def before_attend(filter_name = nil, options ={}, &block) - Sinatra::Event.before_attend(filter_name, options, &block) - end - - # Run given block after each Event's execution - # Example: - # after_attend do - # logger.debug "After event attend!" - # end - # or - # after_attend :clean_up # clean_up is a helper method defined using helpers - # - def after_attend(filter_name = nil, options ={}, &block) - Sinatra::Event.after_attend(filter_name, options, &block) - end - - # Add methods to each event for use during execution - # - # Example: - # helpers do - # def foo - # 'foo!' - # end - # end - # - # get '/bar' do - # foo - # end - # - # get_it '/bar' # => 'foo!' - # - def helpers(&block) - Sinatra::EventContext.class_eval(&block) - end - - # Maps a path to a physical directory containing static files - # - # Example: - # static '/p', 'public' - # - def static(path, root) - Sinatra::StaticEvent.new(path, root) - end - - # Execute block if in environment is equal to env (Used for configuration) - def config_for(env = :development) - yield if Sinatra::Options.environment == env.to_sym - end - - # Define named layouts (default name is :layout) - # - # Examples: - # # Default layout in Erb - # layout do - # '-- <%= yield %> --' - # end - # - # # Named layout in Haml - # layout :for_haml do - # '== XXXX #{yield} XXXX' - # end - # - # # Loads layout named :"foo.erb" from file (default behaviour if block is omitted) - # layout 'foo.erb' # looks for foo.erb. This is odd an is being re-thought - # - # def layout(name = :layout, options = {}) - # Layouts[name] = unless block_given? - # File.read("%s/%s" % [options[:views_directory] || 'views', name]) - # else - # yield - # end - # end - # - # Cool trick: - # - # # Send a one-time layout to renderer method - # get '/cooltrick' do - # erb 'wicked' do - # 'Cool <%= yield %> Trick' - # end - # end - # - # get_it '/cooltrick' # => 'Cool wicked Trick' - # - def layout(name = :layout, options = {}) - Sinatra::Renderer::Layouts[name] = unless block_given? - File.read("%s/%s" % [options[:views_directory] || 'views', name]) - else - yield - end - end - - end - -end - -include Sinatra::Dsl diff --git a/lib/sinatra/environment.rb b/lib/sinatra/environment.rb deleted file mode 100644 index 2e21ecad..00000000 --- a/lib/sinatra/environment.rb +++ /dev/null @@ -1,19 +0,0 @@ -module Sinatra - module Environment - extend self - - def test? - Options.environment == :test - end - - def prepare - Options.parse!(ARGV) - end - - def prepare_loggers(logger = Logger.new(open(Options.log_file, 'w'))) - [Server, EventContext, Event, Dispatcher].each do |klass| - klass.logger = logger - end - end - end -end diff --git a/lib/sinatra/event.rb b/lib/sinatra/event.rb deleted file mode 100644 index 61c39d69..00000000 --- a/lib/sinatra/event.rb +++ /dev/null @@ -1,244 +0,0 @@ -require 'thread' - -module Sinatra - - module EventManager # :nodoc: - extend self - - def reset! - @events.clear if @events - end - - def events - @events || [] - end - - def register_event(event) - (@events ||= []) << event - end - - def determine_event(verb, path, if_nil = :present_error) - event = events.find(method(if_nil)) do |e| - e.verb == verb && e.recognize(path) - end - end - - def present_error - determine_event(:get, '404', :not_found) - end - - def not_found - Event.new(:get, 'not_found', false) do - status 404 - - if request.path_info == '/' && request.request_method == 'GET' - erb :default_index, :views_directory => SINATRA_ROOT + '/files' - else - erb :not_found, :views_directory => SINATRA_ROOT + '/files' - end - end - end - - end - - class Event # :nodoc: - - cattr_accessor :logger - cattr_accessor :after_filters - cattr_accessor :before_filters - - @@mutex = Mutex.new - - self.before_filters = [] - self.after_filters = [] - - def self.reset! - self.before_filters.clear - self.after_filters.clear - end - - def self.before_attend(method_name = nil, options ={}, &block) - setup_filter(:before_filters, method_name, options, &block) - end - - def self.after_attend(method_name = nil, options = {}, &block) - setup_filter(:after_filters, method_name, options, &block) - end - - def self.setup_filter(filter_set_name, method_name, options = {}, &block) - raise "Must specify method or block" if method_name.nil? and !block_given? - value = if block_given? - block - else - method_name - end - insert_index = options[:infront] == true ? 0 : -1 - send(filter_set_name).insert(insert_index, value) - end - - attr_reader :path, :verb - - def initialize(verb, path, register = true, &block) - @verb = verb - @path = path - @route = Route.new(path) - @block = block - EventManager.register_event(self) if register - end - - def attend(request) - request.params.merge!(@route.params) - context = EventContext.new(request) - run_safely do - caught = catch(:halt) do - call_filters(before_filters, context) - end - body = case caught - when :filter_chain_completed - begin - context.instance_eval(&@block) if @block - rescue => e - context.error e - end - when Symbol - context.send(caught) - when String - caught - when Fixnum - context.status caught - end - context.body context.body || body || '' - call_filters(after_filters, context) - end - context.log_event - context - end - alias :call :attend - - def recognize(path) - @route.recognize(path) - end - - private - - def run_safely - if Options.use_mutex? - @@mutex.synchronize do - yield - end - else - yield - end - end - - # Adapted from Merb - # calls a filter chain according to rules. - def call_filters(filter_set, context) - filter_set.each do |filter| - case filter - when Symbol, String - context.send(filter) - when Proc - context.instance_eval(&filter) - end - end - :filter_chain_completed - end - - end - - class StaticEvent < Event # :nodoc: - - def initialize(path, root, register = true) - @root = root - super(:get, path, register) - end - - def recognize(path) - filename = physical_path_for(path) - File.exists?(filename) && File.file?(filename) - end - - def physical_path_for(path) - path.gsub(/^#{@path}/, @root) - end - - def attend(request) - @filename = physical_path_for(request.path_info) - context = EventContext.new(request) - context.body self - context.header 'Content-Type' => MIME_TYPES[File.extname(@filename)[1..-1]] - context.header 'Content-Length' => File.size(@filename).to_s - context - end - - def each - File.open(@filename, "rb") do |file| - while part = file.read(8192) - yield part - end - end - end - - # :stopdoc: - # From WEBrick. - MIME_TYPES = { - "ai" => "application/postscript", - "asc" => "text/plain", - "avi" => "video/x-msvideo", - "bin" => "application/octet-stream", - "bmp" => "image/bmp", - "class" => "application/octet-stream", - "cer" => "application/pkix-cert", - "crl" => "application/pkix-crl", - "crt" => "application/x-x509-ca-cert", - #"crl" => "application/x-pkcs7-crl", - "css" => "text/css", - "dms" => "application/octet-stream", - "doc" => "application/msword", - "dvi" => "application/x-dvi", - "eps" => "application/postscript", - "etx" => "text/x-setext", - "exe" => "application/octet-stream", - "gif" => "image/gif", - "htm" => "text/html", - "html" => "text/html", - "jpe" => "image/jpeg", - "jpeg" => "image/jpeg", - "jpg" => "image/jpeg", - "lha" => "application/octet-stream", - "lzh" => "application/octet-stream", - "mov" => "video/quicktime", - "mpe" => "video/mpeg", - "mpeg" => "video/mpeg", - "mpg" => "video/mpeg", - "pbm" => "image/x-portable-bitmap", - "pdf" => "application/pdf", - "pgm" => "image/x-portable-graymap", - "png" => "image/png", - "pnm" => "image/x-portable-anymap", - "ppm" => "image/x-portable-pixmap", - "ppt" => "application/vnd.ms-powerpoint", - "ps" => "application/postscript", - "qt" => "video/quicktime", - "ras" => "image/x-cmu-raster", - "rb" => "text/plain", - "rd" => "text/plain", - "rtf" => "application/rtf", - "sgm" => "text/sgml", - "sgml" => "text/sgml", - "tif" => "image/tiff", - "tiff" => "image/tiff", - "txt" => "text/plain", - "xbm" => "image/x-xbitmap", - "xls" => "application/vnd.ms-excel", - "xml" => "text/xml", - "xpm" => "image/x-xpixmap", - "xwd" => "image/x-xwindowdump", - "zip" => "application/zip", - } - # :startdoc: - - end - -end diff --git a/lib/sinatra/irb.rb b/lib/sinatra/irb.rb deleted file mode 100644 index 6d35af60..00000000 --- a/lib/sinatra/irb.rb +++ /dev/null @@ -1,56 +0,0 @@ -module Sinatra - - # Sinatra Irb is entered via ruby myapp.rb -c (replace myapp.rb with your app filename) - # - # Be sure to also check out Sinatra::TestMethods for more cool stuff when your in Irb - # - module Irb - extend self - - # taken from merb - def start! #:nodoc: - - Object.send(:include, TestMethods) # added to allow post_to in console - - Object.class_eval do - # Reload all Sinatra and App specific files - def reload! - Loader.reload! - end - - # Show the +body+ with result info in your text editor!!! Great Job! - def show!(editor = nil) - editor = editor || ENV['EDITOR'] - IO.popen(editor, 'w') do |f| - f.puts "" - f.puts - f.puts body - end - nil - end - alias :mate :show! - - def result_info #:nodoc: - info = <<-end_info - # Status: #{status} - # Headers: #{headers.inspect} - end_info - end - end - - ARGV.clear # Avoid passing args to IRB - require 'irb' - require 'irb/completion' - def exit - exit! - end - if File.exists? ".irbrc" - ENV['IRBRC'] = ".irbrc" - end - IRB.start - exit! - end - end -end diff --git a/lib/sinatra/loader.rb b/lib/sinatra/loader.rb deleted file mode 100644 index 0588b62a..00000000 --- a/lib/sinatra/loader.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'set' - -module Sinatra - module Loader - extend self - - def reload! - silence_warnings do - EventManager.reset! - load_files loaded_files - load $0 - end - end - - def load_files(*files) - files = files.flatten - files = files.first if files.first.is_a? Set - - files.each do |file| - file = File.expand_path(file) - load file - loaded_files << file - end - end - alias_method :load_file, :load_files - - def loaded_files - @loaded_files ||= Set.new - end - end -end diff --git a/lib/sinatra/logger.rb b/lib/sinatra/logger.rb deleted file mode 100644 index df7779fd..00000000 --- a/lib/sinatra/logger.rb +++ /dev/null @@ -1,22 +0,0 @@ -module Sinatra - - class Logger - - def initialize(steam) - @stream = steam - end - - %w(info debug error warn).each do |n| - define_method n do |message| - @stream.puts message - @stream.flush - end - end - - def exception(e) - error "#{e.message}:\n\t#{e.backtrace.join("\n\t")}" - end - - end - -end \ No newline at end of file diff --git a/lib/sinatra/options.rb b/lib/sinatra/options.rb deleted file mode 100644 index 1787fd53..00000000 --- a/lib/sinatra/options.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'optparse' - -module Sinatra - module Options - extend self - - attr_with_default :port, 4567 - attr_with_default :environment, :development - attr_with_default :console, nil - attr_with_default :use_mutex, false - - alias :use_mutex? :use_mutex - - def parse!(args) - return if @environment == :test - OptionParser.new do |opts| - opts.on '-p port', '--port port', 'Set the port (default is 4567)' do |port| - @port = port - end - opts.on '-e environment', 'Set the environment (default if development)' do |env| - @environment = env.intern - end - opts.on '-c', '--console', 'Run in console mode' do - @console = true - end - opts.on '-h', '--help', '-?', 'Show this message' do - puts opts - exit! - end - opts.on '-X', '--mutex', 'Use mutex lock when attending events' do - @use_mutex = true - end - end.parse!(ARGV) - end - - def log_file - # TODO find a better way that this - if File.basename($0, '.rb') == 'rake_test_loader' # hack to satisfy rake - '%s.log' % environment - else - File.dirname($0) + ('/%s.log' % environment) - end - end - - def set_environment(env) - @environment = env - end - end -end diff --git a/lib/sinatra/rack_ext/request.rb b/lib/sinatra/rack_ext/request.rb deleted file mode 100644 index f0c928c0..00000000 --- a/lib/sinatra/rack_ext/request.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Rack #:nodoc: - - class Request #:nodoc: - - def request_method - if @env['REQUEST_METHOD'] == 'POST' && %w(PUT DELETE).include?(params['_method']) - params['_method'].upcase - else - @env['REQUEST_METHOD'] - end - end - - end - -end diff --git a/lib/sinatra/route.rb b/lib/sinatra/route.rb deleted file mode 100644 index 7e0007f5..00000000 --- a/lib/sinatra/route.rb +++ /dev/null @@ -1,65 +0,0 @@ -module Sinatra - - class Route - - SYMBOL_FIND = /:[a-z_]+/.freeze - PARENTHETICAL_SEGMENT_STRING = "([^\/.,;?]+)".freeze - - attr_reader :regex, :params - - def initialize(template) - @template = template.to_s.strip - @default_params = { :format => 'html' } - @params = {} - extract_keys - genereate_route - end - - def recognize(path) - @params.clear - - param_values = path.match(@regex).captures.compact rescue nil - - if param_values - keys = @keys.size < param_values.size ? @keys.concat([:format]) : @keys - @params = @default_params.merge(@keys.zip(param_values).to_hash) - true - else - false - end - end - - private - - def extract_keys - @keys = @template.scan(SYMBOL_FIND).map { |raw| eval(raw) } - @keys - end - - def genereate_route_without_format - template = @template.dup - template.gsub!(/\.:format$/, '') - to_regex_route(template) - end - - def genereate_route_with_format - template = @template.dup - if template =~ /\.:format$|\.([\w\d]+)$/ - @default_params[:format] = $1 if $1 - else - template << '.:format' - end - to_regex_route(template) - end - - def to_regex_route(template) - /^#{template.gsub(/\./, '\.').gsub(SYMBOL_FIND, PARENTHETICAL_SEGMENT_STRING)}$/ - end - - def genereate_route - @regex = Regexp.union(genereate_route_without_format, genereate_route_with_format) - end - - end - -end \ No newline at end of file diff --git a/lib/sinatra/server.rb b/lib/sinatra/server.rb deleted file mode 100644 index f32254e3..00000000 --- a/lib/sinatra/server.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'fileutils' - -module Sinatra - - class Server - - cattr_accessor :logger - cattr_accessor :running - - def start - begin - tail_thread = tail(Options.log_file) - Rack::Handler::Mongrel.run(Dispatcher.new, :Port => Options.port) do |server| - puts "== Sinatra has taken the stage on port #{server.port}!" - trap("INT") do - server.stop - self.class.running = false - puts "\n== Sinatra has ended his set (crowd applauds)" - end - end - self.class.running = true - rescue Errno::EADDRINUSE => e - puts "== Someone is already performing on port #{Options.port}!" - logger.exception e - rescue => e - logger.exception e - ensure - tail_thread.kill if tail_thread - end - end - - private - - def tail(log_file) - FileUtils.touch(log_file) - cursor = File.size(log_file) - last_checked = Time.now - tail_thread = Thread.new do - File.open(log_file, 'r') do |f| - loop do - f.seek cursor - if f.mtime > last_checked - last_checked = f.mtime - contents = f.read - cursor += contents.length - print contents - end - sleep 1 - end - end - end - tail_thread - end - - end - -end diff --git a/lib/sinatra/test/methods.rb b/lib/sinatra/test/methods.rb deleted file mode 100644 index eb1cce95..00000000 --- a/lib/sinatra/test/methods.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'uri' - -module Sinatra - - # These methods are for integration testing without an internet connection. They are available in Test::Unit::TestCase and when in Irb. - module Test - - module Methods - - # get_it, post_it, put_it, delete_it - # Executes the method and returns the result of the body - # - # options: - # +:params+ a hash of name parameters - # - # Example: - # get_it '/', :name => 'Blake' # => 'Hello Blake!' - # - %w(get post put delete).each do |verb| - module_eval <<-end_eval - def #{verb}_it(path, params = {}) - request = Rack::MockRequest.new(Sinatra::Dispatcher.new) - @response = request.#{verb} path, :input => generate_input(params) - body - end - end_eval - end - - # The response returned by the Event - def response - @response || Rack::MockResponse.new(404, {}, '') - end - - # The status returned by the event - def status - response.status - end - - # The text returned by the event - def text - response.body - end - alias :xml :text - alias :html :text - alias :body :text - - # The headers returned by the event - def headers - response.headers - end - - private - - def generate_input(params) - params.map { |k,v| "#{k}=#{URI.escape(v)}" }.join('&') - end - - end - - end - -end diff --git a/lib/sinatra/test/spec.rb b/lib/sinatra/test/spec.rb deleted file mode 100644 index fcb38110..00000000 --- a/lib/sinatra/test/spec.rb +++ /dev/null @@ -1,39 +0,0 @@ -require File.dirname(__FILE__) + '/methods' - -module Sinatra - module Test - module Spec - def self.included(base) - silence_warnings do - require File.dirname(__FILE__) + '/../../sinatra' - require 'test/spec' - end - Server.running = true - Options.set_environment :test - Environment.prepare_loggers - EventContext.reraise_errors = true - end - end - end -end - -include Sinatra::Test::Spec - -class Test::Spec::TestCase - - module InstanceMethods - include Sinatra::Test::Methods - end - - alias :initialize_orig :initialize - - def initialize(name, parent=nil, superclass=Test::Unit::TestCase) - initialize_orig(name, parent, superclass) - - @testcase.setup do - Sinatra::EventManager.reset! - Sinatra::Event.reset! - Sinatra::Renderer::Layouts.clear - end - end -end diff --git a/lib/sinatra2.rb b/lib/sinatra2.rb deleted file mode 100644 index af6e3c90..00000000 --- a/lib/sinatra2.rb +++ /dev/null @@ -1,65 +0,0 @@ -require "rubygems" -require "rack" - -class String - def to_param - URI.escape(self) - end - - def from_param - URI.unescape(self) - end -end - -class Symbol - def to_proc - Proc.new { |*args| args.shift.__send__(self, *args) } - end -end - -class Array - def to_hash - self.inject({}) { |h, (k, v)| h[k] = v; h } - end -end - -module Sinatra - extend self - - def request_types - @request_types ||= %w(GET PUT POST DELETE) - end - - def events - @events ||= Hash.new do |hash, key| - hash[key] = [] if request_types.include?(key) - end - end - - class Route - - URI_CHAR = '[^/?:,&#]'.freeze unless defined?(URI_CHAR) - PARAM = /:(#{URI_CHAR}+)/.freeze unless defined?(PARAM) - - def initialize(path, &b) - @path, @block = path, b - @param_keys = [] - regex = path.to_s.gsub(PARAM) do - @param_keys << $1.intern - "(#{URI_CHAR}+)" - end - @pattern = /^#{regex}$/ - @struct = Struct.new(:block, :params) - end - - def match(path) - return nil unless path =~ @pattern - params = @param_keys.zip($~.captures.map(&:from_param)).to_hash - @struct.new(@block, params) - end - - end - -end - - diff --git a/site/index.htm b/site/index.htm deleted file mode 100644 index 37ae08bb..00000000 --- a/site/index.htm +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - Sinatra : Classy web-development dressed in a DSL - - - - - -
- -
-
-
-

- Install!
-

gem install sinatra -y
-

-

- Require! (any filename you wish)
-

-# lyrics.rb
-require 'rubygems'
-require 'sinatra'
- yup.. that's it for a sec
-

-

- Run!
-

ruby lyrics.rb
-

-

- Bask!
-

http://localhost:4567
-

-

- Write! -

-get '/' do
-  "Now that's a fine looking dame!"
-end
-

-

- Examples!
-

here
-

-

- Docs!
-

here
-

-

- Can you digg it cats?
-

here
-

-

- Contribute!
-

using git
-

- -
-
-
- - diff --git a/site/index.html b/site/index.html deleted file mode 100644 index 37ae08bb..00000000 --- a/site/index.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - Sinatra : Classy web-development dressed in a DSL - - - - - -
- -
-
-
-

- Install!
-

gem install sinatra -y
-

-

- Require! (any filename you wish)
-

-# lyrics.rb
-require 'rubygems'
-require 'sinatra'
- yup.. that's it for a sec
-

-

- Run!
-

ruby lyrics.rb
-

-

- Bask!
-

http://localhost:4567
-

-

- Write! -

-get '/' do
-  "Now that's a fine looking dame!"
-end
-

-

- Examples!
-

here
-

-

- Docs!
-

here
-

-

- Can you digg it cats?
-

here
-

-

- Contribute!
-

using git
-

- -
-
-
- - diff --git a/site/logo.png b/site/logo.png deleted file mode 100644 index a0d868a0405ea2321400aa909a15fcf71e7cff6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26576 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 'DELETE' - status.should.equal 200 - text.should.equal 'DELETE' - end - -end diff --git a/test/sinatra/event_test.rb b/test/sinatra/event_test.rb deleted file mode 100644 index d63010d2..00000000 --- a/test/sinatra/event_test.rb +++ /dev/null @@ -1,44 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -describe "Event" do - - it "should return 500 if exception thrown" do - Sinatra::Environment.prepare_loggers stub_everything - - Sinatra::EventContext.any_instance.expects(:reraise_errors).returns(false) - - event = Sinatra::Event.new(:get, '/') do - raise 'whaaaa!' - end - - result = event.attend(stub_everything(:params => {}, :path_info => '/')) - - result.status.should.equal 500 - end - - it "custom error if present" do - Sinatra::Environment.prepare_loggers stub_everything - - event = Sinatra::Event.new(:get, '404') do - body 'custom 404' - end - - Sinatra::EventManager.expects(:not_found).never - Sinatra::EventManager.determine_event(:get, '/sdf') - end - - it "should show default 404 if custom not present" do - Sinatra::EventManager.expects(:not_found) - Sinatra::EventManager.determine_event(:get, '/asdfsasd') - end - - it "should not execute event if halted" do - Sinatra::Event.before_filters << lambda { throw :halt, 'whoa!' } - event = Sinatra::Event.new(:get, '/') do - foo - end - event.expects(:foo).never - get_it('/').should.equal 'whoa!' - end - -end diff --git a/test/sinatra/filter_test.rb b/test/sinatra/filter_test.rb deleted file mode 100644 index 0623ec73..00000000 --- a/test/sinatra/filter_test.rb +++ /dev/null @@ -1,19 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -context "Filter" do - - specify "befores can be in front" do - before_attend :bar - before_attend :foo, :infront => true - - Sinatra::Event.before_filters.should.equal [:foo, :bar] - end - - specify "afters can be in front" do - after_attend :bar - after_attend :foo, :infront => true - - Sinatra::Event.after_filters.should.equal [:foo, :bar] - end - -end \ No newline at end of file diff --git a/test/sinatra/haml_test.rb b/test/sinatra/haml_test.rb deleted file mode 100644 index 2912ac64..00000000 --- a/test/sinatra/haml_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - - -context "Haml" do - - specify "does layouts" do - layout do - '%h1== Hello #{yield}' - end - - get "/" do - haml 'Ben' - end - - get_it '/' - - body.should.equal "

Hello Ben

\n" - end - -end - diff --git a/test/sinatra/renderer_test.rb b/test/sinatra/renderer_test.rb deleted file mode 100644 index f4ffca7f..00000000 --- a/test/sinatra/renderer_test.rb +++ /dev/null @@ -1,46 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -class Sinatra::EventContext # :nodoc: - - def render_foo(template) - require 'erb' - ERB.new(template).result(binding) - end - -end - -describe "Renderer" do - - before(:each) do - @context = Sinatra::EventContext.new(stub()) - end - - it "should render render a tempalate" do - @context.render('foo', :foo).should.equal 'foo' - end - - it "should render with a layout if given" do - result = @context.render('content', :foo) do - 'X <%= yield %> X' - end - - result.should.equal 'X content X' - end - - it "should render default layout if it exists and layout if no layout name given" do - Sinatra::Renderer::Layouts[:layout] = 'X <%= yield %> Y' - @context.render('foo', :foo).should.equal 'X foo Y' - - Sinatra::Renderer::Layouts[:foo] = 'Foo <%= yield %> Layout' - @context.render('bar', :foo, :layout => :foo).should.equal 'Foo bar Layout' - end - - it "should read template from a file if exists" do - File.expects(:read).with('views/bar.foo').returns('foo content') - @context.render(:bar, :foo).should.equal 'foo content' - - File.expects(:read).with('views2/bar.foo').returns('foo content') - @context.render(:bar, :foo, :views_directory => 'views2').should.equal 'foo content' - end - -end diff --git a/test/sinatra/request_test.rb b/test/sinatra/request_test.rb deleted file mode 100644 index de75f843..00000000 --- a/test/sinatra/request_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -describe "Rack::Request" do - it "should return PUT and DELETE based on _method param" do - env = {'REQUEST_METHOD' => 'POST', 'rack.input' => StringIO.new('_method=DELETE')} - Rack::Request.new(env).request_method.should.equal 'DELETE' - - env = {'REQUEST_METHOD' => 'POST', 'rack.input' => StringIO.new('_method=PUT')} - Rack::Request.new(env).request_method.should.equal 'PUT' - end - - it "should not allow faking" do - env = {'REQUEST_METHOD' => 'POST', 'rack.input' => StringIO.new('_method=GET')} - Rack::Request.new(env).request_method.should.equal 'POST' - - env = {'REQUEST_METHOD' => 'GET', 'rack.input' => StringIO.new('_method=POST')} - Rack::Request.new(env).request_method.should.equal 'GET' - end -end - - diff --git a/test/sinatra/route_test.rb b/test/sinatra/route_test.rb deleted file mode 100644 index 8ea5466f..00000000 --- a/test/sinatra/route_test.rb +++ /dev/null @@ -1,21 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -describe "Route" do - it "gives :format for free" do - route = Sinatra::Route.new('/foo/:test/:blake') - - route.recognize('/foo/bar/baz').should.equal true - route.params.should.equal :test => 'bar', :blake => 'baz', :format => 'html' - - route.recognize('/foo/bar/baz.xml').should.equal true - route.params.should.equal :test => 'bar', :blake => 'baz', :format => 'xml' - end - - it "doesn't auto add :format for routes with explicit formats" do - route = Sinatra::Route.new('/foo/:test.xml') - route.recognize('/foo/bar').should.equal false - route.recognize('/foo/bar.xml').should.equal true - route.params.should.equal :test => 'bar', :format => 'xml' - end -end - diff --git a/test/sinatra/static_files/foo.txt b/test/sinatra/static_files/foo.txt deleted file mode 100644 index 7cc4bc43..00000000 --- a/test/sinatra/static_files/foo.txt +++ /dev/null @@ -1 +0,0 @@ -You found foo! \ No newline at end of file diff --git a/test/sinatra/static_files_test.rb b/test/sinatra/static_files_test.rb deleted file mode 100644 index 24aeb2ef..00000000 --- a/test/sinatra/static_files_test.rb +++ /dev/null @@ -1,44 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' -require 'stringio' - -context "StaticEvent" do - - specify "recognizes paths prefixed with it's path" do - File.expects(:exists?).with('/x/bar/test.jpg').returns(true) - File.expects(:file?).with('/x/bar/test.jpg').returns(true) - Sinatra::StaticEvent.new('/foo', '/x/bar').recognize('/foo/test.jpg').should.equal true - - File.expects(:exists?).with('/x/bar/test.jpg').returns(false) - Sinatra::StaticEvent.new('/foo', '/x/bar').recognize('/foo/test.jpg').should.equal false - end - - specify "sets headers for file type" do - File.expects(:open).with('/x/bar/test.jpg', 'rb').returns(StringIO.new) - File.expects(:size).with('/x/bar/test.jpg').returns(255) - result = Sinatra::StaticEvent.new('/foo', '/x/bar').attend(stub(:path_info => '/foo/test.jpg')) - result.headers.should.equal 'Content-Type' => 'image/jpeg', 'Content-Length' => '255' - result.body.each { } - end - - specify "makes sure it is a file and not a directory" do - File.expects(:exists?).with('/x/bar').returns(true) - File.expects(:file?).with('/x/bar').returns(false) - Sinatra::StaticEvent.new('/foo', '/x').recognize('/foo/bar').should.equal false - end - -end - -context "StaticEvent (In full context)" do - - specify "should serve a static file" do - e = static '/x', root = File.dirname(__FILE__) + '/static_files' - - File.read(e.physical_path_for('/x/foo.txt')).should.equal 'You found foo!' - - get_it '/x/foo.txt' - - status.should.equal 200 - body.should.equal 'You found foo!' - end - -end \ No newline at end of file diff --git a/test/sinatra/url_test.rb b/test/sinatra/url_test.rb deleted file mode 100644 index f340cdb7..00000000 --- a/test/sinatra/url_test.rb +++ /dev/null @@ -1,16 +0,0 @@ -require File.dirname(__FILE__) + '/../helper' - -describe "Route" do - - it "should recognize params in urls" do - route = Sinatra::Route.new('/foo/:test/:blake') - - route.recognize('/foo/bar/baz').should.equal true - route.params.should.equal :test => 'bar', :blake => 'baz', :format => 'html' - - route.recognize('/foo/bar/baz.xml').should.equal true - route.params.should.equal :test => 'bar', :blake => 'baz', :format => 'xml' - end - -end - diff --git a/vendor/erb/init.rb b/vendor/erb/init.rb deleted file mode 100644 index 4d594284..00000000 --- a/vendor/erb/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -require File.dirname(__FILE__) + '/lib/erb' - -Sinatra::EventContext.send(:include, Sinatra::Erb::EventContext) diff --git a/vendor/erb/lib/erb.rb b/vendor/erb/lib/erb.rb deleted file mode 100644 index baa8c9b3..00000000 --- a/vendor/erb/lib/erb.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Sinatra - - module Erb # :nodoc: - - module EventContext - - # Renders raw erb in within the events context. - # - # This can be use to if you already have the template on hand and don't - # need a layout. This is speedier than using erb - # - def render_erb(content) - require 'erb' - body ERB.new(content).result(binding) - end - - # Renders erb within an event. - # - # Inline example: - # - # get '/foo' do - # erb 'The time is <%= Time.now %>' - # end - # - # Template example: - # - # get '/foo' do - # erb :foo #=> reads and renders view/foo.erb - # end - # - # For options, see Sinatra::Renderer - # - # See also: Sinatra::Renderer - def erb(template, options = {}, &layout) - render(template, :erb, options, &layout) - end - end - - end - -end diff --git a/vendor/haml/init.rb b/vendor/haml/init.rb deleted file mode 100644 index dd88d6cd..00000000 --- a/vendor/haml/init.rb +++ /dev/null @@ -1,3 +0,0 @@ -require File.dirname(__FILE__) + '/lib/haml' - -Sinatra::EventContext.send(:include, Sinatra::Haml::EventContext) diff --git a/vendor/haml/lib/haml.rb b/vendor/haml/lib/haml.rb deleted file mode 100644 index fe37372f..00000000 --- a/vendor/haml/lib/haml.rb +++ /dev/null @@ -1,41 +0,0 @@ -module Sinatra - - module Haml # :nodoc: - - module EventContext - - # Renders raw haml in within the events context. - # - # This can be use to if you already have the template on hand and don't - # need a layout. This is speedier than using haml - # - def render_haml(template, &block) - require 'haml' - body ::Haml::Engine.new(template).render(self, &block) - end - - # Renders Haml within an event. - # - # Inline example: - # - # get '/foo' do - # haml '== The time is #{Time.now}' - # end - # - # Template example: - # - # get '/foo' do - # haml :foo #=> reads and renders view/foo.haml - # end - # - # For options, see Sinatra::Renderer - # - # See also: Sinatra::Renderer - def haml(template, options = {}, &layout) - render(template, :haml, options, &layout) - end - end - - end - -end