rtomayko-sinatra 0.3.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.
Files changed (49) hide show
  1. data/ChangeLog +64 -0
  2. data/LICENSE +22 -0
  3. data/README.rdoc +533 -0
  4. data/Rakefile +111 -0
  5. data/images/404.png +0 -0
  6. data/images/500.png +0 -0
  7. data/lib/sinatra/rack/handler/mongrel.rb +85 -0
  8. data/lib/sinatra/test/methods.rb +76 -0
  9. data/lib/sinatra/test/rspec.rb +10 -0
  10. data/lib/sinatra/test/spec.rb +10 -0
  11. data/lib/sinatra/test/unit.rb +13 -0
  12. data/lib/sinatra.rb +1477 -0
  13. data/sinatra.gemspec +78 -0
  14. data/test/app_test.rb +299 -0
  15. data/test/application_test.rb +318 -0
  16. data/test/builder_test.rb +101 -0
  17. data/test/custom_error_test.rb +62 -0
  18. data/test/erb_test.rb +136 -0
  19. data/test/event_context_test.rb +15 -0
  20. data/test/events_test.rb +47 -0
  21. data/test/filter_test.rb +30 -0
  22. data/test/haml_test.rb +233 -0
  23. data/test/helper.rb +7 -0
  24. data/test/mapped_error_test.rb +72 -0
  25. data/test/pipeline_test.rb +66 -0
  26. data/test/public/foo.xml +1 -0
  27. data/test/sass_test.rb +57 -0
  28. data/test/sessions_test.rb +39 -0
  29. data/test/streaming_test.rb +118 -0
  30. data/test/sym_params_test.rb +19 -0
  31. data/test/template_test.rb +30 -0
  32. data/test/use_in_file_templates_test.rb +47 -0
  33. data/test/views/foo.builder +1 -0
  34. data/test/views/foo.erb +1 -0
  35. data/test/views/foo.haml +1 -0
  36. data/test/views/foo.sass +2 -0
  37. data/test/views/foo_layout.erb +2 -0
  38. data/test/views/foo_layout.haml +2 -0
  39. data/test/views/layout_test/foo.builder +1 -0
  40. data/test/views/layout_test/foo.erb +1 -0
  41. data/test/views/layout_test/foo.haml +1 -0
  42. data/test/views/layout_test/foo.sass +2 -0
  43. data/test/views/layout_test/layout.builder +3 -0
  44. data/test/views/layout_test/layout.erb +1 -0
  45. data/test/views/layout_test/layout.haml +1 -0
  46. data/test/views/layout_test/layout.sass +2 -0
  47. data/test/views/no_layout/no_layout.builder +1 -0
  48. data/test/views/no_layout/no_layout.haml +1 -0
  49. metadata +130 -0
data/Rakefile ADDED
@@ -0,0 +1,111 @@
1
+ require 'rake/clean'
2
+
3
+ task :default => :test
4
+
5
+ # SPECS ===============================================================
6
+
7
+ desc 'Run specs with story style output'
8
+ task :spec do
9
+ sh 'specrb --specdox -Ilib:test test/*_test.rb'
10
+ end
11
+
12
+ desc 'Run specs with unit test style output'
13
+ task :test => FileList['test/*_test.rb'] do |t|
14
+ suite = t.prerequisites.map{|f| "-r#{f.chomp('.rb')}"}.join(' ')
15
+ sh "ruby -Ilib:test #{suite} -e ''", :verbose => false
16
+ end
17
+
18
+ # PACKAGING ============================================================
19
+
20
+ # Load the gemspec using the same limitations as github
21
+ def spec
22
+ @spec ||=
23
+ begin
24
+ require 'rubygems/specification'
25
+ data = File.read('sinatra.gemspec')
26
+ spec = nil
27
+ Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
28
+ spec
29
+ end
30
+ end
31
+
32
+ def package(ext='')
33
+ "dist/sinatra-#{spec.version}" + ext
34
+ end
35
+
36
+ desc 'Build packages'
37
+ task :package => %w[.gem .tar.gz].map {|e| package(e)}
38
+
39
+ desc 'Build and install as local gem'
40
+ task :install => package('.gem') do
41
+ sh "gem install #{package('.gem')}"
42
+ end
43
+
44
+ directory 'dist/'
45
+
46
+ file package('.gem') => %w[dist/ sinatra.gemspec] + spec.files do |f|
47
+ sh "gem build sinatra.gemspec"
48
+ mv File.basename(f.name), f.name
49
+ end
50
+
51
+ file package('.tar.gz') => %w[dist/] + spec.files do |f|
52
+ sh "git archive --format=tar HEAD | gzip > #{f.name}"
53
+ end
54
+
55
+ # Rubyforge Release / Publish Tasks ==================================
56
+
57
+ desc 'Publish API docs to rubyforge'
58
+ task 'publish:doc' => 'doc/api/index.html' do
59
+ sh 'scp -rp doc/* rubyforge.org:/var/www/gforge-projects/sinatra/'
60
+ end
61
+
62
+ task 'publish:gem' => [package('.gem'), package('.tar.gz')] do |t|
63
+ sh <<-end
64
+ rubyforge add_release sinatra sinatra #{spec.version} #{package('.gem')} &&
65
+ rubyforge add_file sinatra sinatra #{spec.version} #{package('.tar.gz')}
66
+ end
67
+ end
68
+
69
+ # Gemspec Helpers ====================================================
70
+
71
+ file 'sinatra.gemspec' => FileList['{lib,test,images}/**','Rakefile'] do |f|
72
+ # read spec file and split out manifest section
73
+ spec = File.read(f.name)
74
+ parts = spec.split(" # = MANIFEST =\n")
75
+ fail 'bad spec' if parts.length != 3
76
+ # determine file list from git ls-files
77
+ files = `git ls-files`.
78
+ split("\n").
79
+ sort.
80
+ reject{ |file| file =~ /^\./ }.
81
+ map{ |file| " #{file}" }.
82
+ join("\n")
83
+ # piece file back together and write...
84
+ parts[1] = " s.files = %w[\n#{files}\n ]\n"
85
+ spec = parts.join(" # = MANIFEST =\n")
86
+ File.open(f.name, 'w') { |io| io.write(spec) }
87
+ puts "updated #{f.name}"
88
+ end
89
+
90
+ # Hanna RDoc =========================================================
91
+ #
92
+ # Building docs requires the hanna gem:
93
+ # gem install mislav-hanna --source=http://gems.github.com
94
+
95
+ desc 'Generate Hanna RDoc under doc/api'
96
+ task :doc => ['doc/api/index.html']
97
+
98
+ file 'doc/api/index.html' => FileList['lib/**/*.rb','README.rdoc'] do |f|
99
+ rb_files = f.prerequisites
100
+ sh((<<-end).gsub(/\s+/, ' '))
101
+ hanna --charset utf8 \
102
+ --fmt html \
103
+ --inline-source \
104
+ --line-numbers \
105
+ --main README.rdoc \
106
+ --op doc/api \
107
+ --title 'Sinatra API Documentation' \
108
+ #{rb_files.join(' ')}
109
+ end
110
+ end
111
+ CLEAN.include 'doc/api'
data/images/404.png ADDED
Binary file
data/images/500.png ADDED
Binary file
@@ -0,0 +1,85 @@
1
+ require 'mongrel'
2
+ require 'stringio'
3
+
4
+
5
+ module Rack
6
+ module Handler
7
+ class Mongrel < ::Mongrel::HttpHandler
8
+ def self.run(app, options={})
9
+ server = ::Mongrel::HttpServer.new(options[:Host] || '0.0.0.0',
10
+ options[:Port] || 8080)
11
+ # Acts like Rack::URLMap, utilizing Mongrel's own path finding methods.
12
+ # Use is similar to #run, replacing the app argument with a hash of
13
+ # { path=>app, ... } or an instance of Rack::URLMap.
14
+ if options[:map]
15
+ if app.is_a? Hash
16
+ app.each do |path, appl|
17
+ path = '/'+path unless path[0] == ?/
18
+ server.register(path, Rack::Handler::Mongrel.new(appl))
19
+ end
20
+ elsif app.is_a? URLMap
21
+ app.instance_variable_get(:@mapping).each do |(host, path, appl)|
22
+ next if !host.nil? && !options[:Host].nil? && options[:Host] != host
23
+ path = '/'+path unless path[0] == ?/
24
+ server.register(path, Rack::Handler::Mongrel.new(appl))
25
+ end
26
+ else
27
+ raise ArgumentError, "first argument should be a Hash or URLMap"
28
+ end
29
+ else
30
+ server.register('/', Rack::Handler::Mongrel.new(app))
31
+ end
32
+ yield server if block_given?
33
+ server.run.join
34
+ end
35
+
36
+ def initialize(app)
37
+ @app = app
38
+ end
39
+
40
+ def process(request, response)
41
+ env = {}.replace(request.params)
42
+ env.delete "HTTP_CONTENT_TYPE"
43
+ env.delete "HTTP_CONTENT_LENGTH"
44
+
45
+ env["SCRIPT_NAME"] = "" if env["SCRIPT_NAME"] == "/"
46
+
47
+ env.update({"rack.version" => [0,1],
48
+ "rack.input" => request.body || StringIO.new(""),
49
+ "rack.errors" => STDERR,
50
+
51
+ "rack.multithread" => true,
52
+ "rack.multiprocess" => false, # ???
53
+ "rack.run_once" => false,
54
+
55
+ "rack.url_scheme" => "http",
56
+ })
57
+ env["QUERY_STRING"] ||= ""
58
+ env.delete "PATH_INFO" if env["PATH_INFO"] == ""
59
+
60
+ status, headers, body = @app.call(env)
61
+
62
+ begin
63
+ response.status = status.to_i
64
+ headers.each { |k, vs|
65
+ vs.each { |v|
66
+ response.header[k] = v
67
+ }
68
+ }
69
+ # taken from Merb until we have a better solution that conforms
70
+ # to the Rack::Standard
71
+ if Proc === body
72
+ body.call(response)
73
+ else
74
+ body.each { |part|
75
+ response.body << part
76
+ }
77
+ end
78
+ response.finished
79
+ ensure
80
+ body.close if body.respond_to? :close
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,76 @@
1
+ module Sinatra
2
+
3
+ module Test
4
+
5
+ module Methods
6
+ include Rack::Utils
7
+
8
+ ENV_KEY_NAMES = {
9
+ :accept => "HTTP_ACCEPT",
10
+ :agent => "HTTP_USER_AGENT",
11
+ :host => "HTTP_HOST",
12
+ :session => "HTTP_COOKIE",
13
+ :cookies => "HTTP_COOKIE",
14
+ :content_type => "CONTENT_TYPE"
15
+ }
16
+
17
+ def session(data, key = 'rack.session')
18
+ data = data.from_params if data.respond_to?(:from_params)
19
+ "#{escape(key)}=#{[Marshal.dump(data)].pack("m*")}"
20
+ end
21
+
22
+ def normalize_rack_environment(env)
23
+ env.inject({}) do |hash,(k,v)|
24
+ hash[ENV_KEY_NAMES[k] || k] = v
25
+ hash
26
+ end
27
+ end
28
+
29
+ def hash_to_param_string(hash)
30
+ hash.map { |pair| pair.map{|v|escape(v)}.join('=') }.join('&')
31
+ end
32
+
33
+ %w(get head post put delete).each do |verb|
34
+ http_method = verb.upcase
35
+ define_method("#{verb}_it") do |path, *args|
36
+ @request = Rack::MockRequest.new(Sinatra.build_application)
37
+ opts, input =
38
+ case args.size
39
+ when 2 # input, env
40
+ input, env = args
41
+ [env, input]
42
+ when 1 # params
43
+ if (data = args.first).kind_of?(Hash)
44
+ env = (data.delete(:env) || {})
45
+ [env, hash_to_param_string(data)]
46
+ else
47
+ [{}, data]
48
+ end
49
+ when 0
50
+ [{}, '']
51
+ else
52
+ raise ArgumentError, "zero, one, or two arguments expected"
53
+ end
54
+ opts = normalize_rack_environment(opts)
55
+ opts[:input] ||= input
56
+ @response = @request.request(http_method, path, opts)
57
+ end
58
+ end
59
+
60
+ def follow!
61
+ get_it(@response.location)
62
+ end
63
+
64
+ def method_missing(name, *args)
65
+ if @response.respond_to?(name)
66
+ @response.send(name, *args)
67
+ else
68
+ super
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/unit'
2
+ require 'spec/interop/test'
3
+
4
+ class Test::Unit::TestCase
5
+
6
+ def should
7
+ @response.should
8
+ end
9
+
10
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/unit'
2
+ require 'test/spec'
3
+
4
+ class Test::Unit::TestCase
5
+
6
+ def should
7
+ @response.should
8
+ end
9
+
10
+ end
@@ -0,0 +1,13 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/methods'
3
+
4
+ Test::Unit::TestCase.send(:include, Sinatra::Test::Methods)
5
+
6
+ Sinatra::Application.default_options.merge!(
7
+ :env => :test,
8
+ :run => false,
9
+ :raise_errors => true,
10
+ :logging => false
11
+ )
12
+
13
+ Sinatra.application = nil