pirj-sinatra-contrib 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +135 -0
  3. data/Rakefile +61 -0
  4. data/ideas.md +29 -0
  5. data/lib/sinatra/capture.rb +42 -0
  6. data/lib/sinatra/config_file.rb +151 -0
  7. data/lib/sinatra/content_for.rb +111 -0
  8. data/lib/sinatra/contrib.rb +39 -0
  9. data/lib/sinatra/contrib/all.rb +2 -0
  10. data/lib/sinatra/contrib/setup.rb +53 -0
  11. data/lib/sinatra/contrib/version.rb +45 -0
  12. data/lib/sinatra/decompile.rb +113 -0
  13. data/lib/sinatra/engine_tracking.rb +96 -0
  14. data/lib/sinatra/extension.rb +95 -0
  15. data/lib/sinatra/json.rb +134 -0
  16. data/lib/sinatra/link_header.rb +132 -0
  17. data/lib/sinatra/namespace.rb +282 -0
  18. data/lib/sinatra/reloader.rb +384 -0
  19. data/lib/sinatra/respond_with.rb +245 -0
  20. data/lib/sinatra/streaming.rb +267 -0
  21. data/lib/sinatra/test_helpers.rb +87 -0
  22. data/sinatra-contrib.gemspec +121 -0
  23. data/spec/capture_spec.rb +80 -0
  24. data/spec/config_file/key_value.yml +6 -0
  25. data/spec/config_file/missing_env.yml +4 -0
  26. data/spec/config_file/with_envs.yml +7 -0
  27. data/spec/config_file/with_nested_envs.yml +11 -0
  28. data/spec/config_file_spec.rb +44 -0
  29. data/spec/content_for/different_key.erb +1 -0
  30. data/spec/content_for/different_key.erubis +1 -0
  31. data/spec/content_for/different_key.haml +2 -0
  32. data/spec/content_for/different_key.slim +2 -0
  33. data/spec/content_for/layout.erb +1 -0
  34. data/spec/content_for/layout.erubis +1 -0
  35. data/spec/content_for/layout.haml +1 -0
  36. data/spec/content_for/layout.slim +1 -0
  37. data/spec/content_for/multiple_blocks.erb +4 -0
  38. data/spec/content_for/multiple_blocks.erubis +4 -0
  39. data/spec/content_for/multiple_blocks.haml +8 -0
  40. data/spec/content_for/multiple_blocks.slim +8 -0
  41. data/spec/content_for/multiple_yields.erb +3 -0
  42. data/spec/content_for/multiple_yields.erubis +3 -0
  43. data/spec/content_for/multiple_yields.haml +3 -0
  44. data/spec/content_for/multiple_yields.slim +3 -0
  45. data/spec/content_for/passes_values.erb +1 -0
  46. data/spec/content_for/passes_values.erubis +1 -0
  47. data/spec/content_for/passes_values.haml +1 -0
  48. data/spec/content_for/passes_values.slim +1 -0
  49. data/spec/content_for/same_key.erb +1 -0
  50. data/spec/content_for/same_key.erubis +1 -0
  51. data/spec/content_for/same_key.haml +2 -0
  52. data/spec/content_for/same_key.slim +2 -0
  53. data/spec/content_for/takes_values.erb +1 -0
  54. data/spec/content_for/takes_values.erubis +1 -0
  55. data/spec/content_for/takes_values.haml +3 -0
  56. data/spec/content_for/takes_values.slim +3 -0
  57. data/spec/content_for_spec.rb +201 -0
  58. data/spec/decompile_spec.rb +44 -0
  59. data/spec/extension_spec.rb +33 -0
  60. data/spec/json_spec.rb +115 -0
  61. data/spec/link_header_spec.rb +100 -0
  62. data/spec/namespace/foo.erb +1 -0
  63. data/spec/namespace/nested/foo.erb +1 -0
  64. data/spec/namespace_spec.rb +623 -0
  65. data/spec/okjson.rb +581 -0
  66. data/spec/reloader/app.rb.erb +40 -0
  67. data/spec/reloader_spec.rb +441 -0
  68. data/spec/respond_with/bar.erb +1 -0
  69. data/spec/respond_with/bar.json.erb +1 -0
  70. data/spec/respond_with/foo.html.erb +1 -0
  71. data/spec/respond_with/not_html.sass +2 -0
  72. data/spec/respond_with_spec.rb +289 -0
  73. data/spec/spec_helper.rb +6 -0
  74. data/spec/streaming_spec.rb +436 -0
  75. metadata +252 -0
@@ -0,0 +1,39 @@
1
+ require 'sinatra/contrib/setup'
2
+
3
+ module Sinatra
4
+ module Contrib
5
+ ##
6
+ # Common middleware that doesn't bring run time overhead if not used
7
+ # or breaks if external dependencies are missing. Will extend
8
+ # Sinatra::Application by default.
9
+ module Common
10
+ register :ConfigFile
11
+ register :MultiRoute
12
+ register :Namespace
13
+ register :RespondWith
14
+
15
+ helpers :Capture
16
+ helpers :ContentFor
17
+ helpers :Cookies
18
+ helpers :EngineTracking
19
+ helpers :JSON
20
+ helpers :LinkHeader
21
+ helpers :Streaming
22
+ end
23
+
24
+ ##
25
+ # Other extensions you don't want to be loaded unless needed.
26
+ module Custom
27
+ # register :Compass
28
+ register :Decompile
29
+ register :Reloader
30
+ end
31
+
32
+ ##
33
+ # Stuff that aren't Sinatra extensions, technically.
34
+ autoload :Extension
35
+ autoload :TestHelpers
36
+ end
37
+
38
+ register Sinatra::Contrib::Common
39
+ end
@@ -0,0 +1,2 @@
1
+ require 'sinatra/contrib'
2
+ Sinatra.register Sinatra::Contrib::All
@@ -0,0 +1,53 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra/contrib/version'
3
+ require 'backports'
4
+
5
+ module Sinatra
6
+ module Contrib
7
+ module Loader
8
+ def extensions
9
+ @extensions ||= {:helpers => [], :register => []}
10
+ end
11
+
12
+ def register(name, path = nil)
13
+ autoload name, path, :register
14
+ end
15
+
16
+ def helpers(name, path = nil)
17
+ autoload name, path, :helpers
18
+ end
19
+
20
+ def autoload(name, path = nil, method = nil)
21
+ path ||= "sinatra/#{name.to_s.underscore}"
22
+ extensions[method] << name if method
23
+ Sinatra.autoload(name, path)
24
+ end
25
+
26
+ def registered(base)
27
+ @extensions.each do |meth, list|
28
+ list = list.map { |name| Sinatra.const_get name }
29
+ base.send(meth, *list) unless base == ::Sinatra::Application
30
+ end
31
+ end
32
+ end
33
+
34
+ module Common
35
+ extend Loader
36
+ end
37
+
38
+ module Custom
39
+ extend Loader
40
+ end
41
+
42
+ module All
43
+ def self.registered(base)
44
+ base.register Common, Custom
45
+ end
46
+ end
47
+
48
+ extend Loader
49
+ def self.registered(base)
50
+ base.register Common, Custom
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,45 @@
1
+ module Sinatra
2
+ module Contrib
3
+ def self.version
4
+ VERSION
5
+ end
6
+
7
+ module VERSION
8
+ extend Comparable
9
+
10
+ MAJOR = 1
11
+ MINOR = 3
12
+ TINY = 0
13
+ SIGNATURE = [MAJOR, MINOR, TINY]
14
+ STRING = SIGNATURE.join '.'
15
+
16
+ def self.major; MAJOR end
17
+ def self.minor; MINOR end
18
+ def self.tiny; TINY end
19
+ def self.to_s; STRING end
20
+
21
+ def self.hash
22
+ STRING.hash
23
+ end
24
+
25
+ def self.<=>(other)
26
+ other = other.split('.').map { |i| i.to_i } if other.respond_to? :split
27
+ SIGNATURE <=> Array(other)
28
+ end
29
+
30
+ def self.inspect
31
+ STRING.inspect
32
+ end
33
+
34
+ def self.respond_to?(meth, *)
35
+ return true if super
36
+ meth.to_s !~ /^__|^to_str$/ and STRING.respond_to? meth
37
+ end
38
+
39
+ def self.method_missing(meth, *args, &block)
40
+ return super unless STRING.respond_to?(meth)
41
+ STRING.send(meth, *args, &block)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,113 @@
1
+ require 'sinatra/base'
2
+ require 'backports'
3
+ require 'uri'
4
+
5
+ module Sinatra
6
+
7
+ # = Sinatra::Decompile
8
+ #
9
+ # <tt>Sinatra::Decompile</tt> is an extension that provides a method,
10
+ # conveniently called +decompile+, that will generate a String pattern for a
11
+ # given route.
12
+ #
13
+ # == Usage
14
+ #
15
+ # === Classic Application
16
+ #
17
+ # To use the extension in a classic application all you need to do is require
18
+ # it:
19
+ #
20
+ # require "sinatra"
21
+ # require "sinatra/decompile"
22
+ #
23
+ # # Your classic application code goes here...
24
+ #
25
+ # This will add the +decompile+ method to the application/class scope, but
26
+ # you can also call it as <tt>Sinatra::Decompile.decompile</tt>.
27
+ #
28
+ # === Modular Application
29
+ #
30
+ # To use the extension in a modular application you need to require it, and
31
+ # then, tell the application you will use it:
32
+ #
33
+ # require "sinatra/base"
34
+ # require "sinatra/decompile"
35
+ #
36
+ # class MyApp < Sinatra::Base
37
+ # register Sinatra::Decompile
38
+ #
39
+ # # The rest of your modular application code goes here...
40
+ # end
41
+ #
42
+ # This will add the +decompile+ method to the application/class scope. You
43
+ # can choose not to register the extension, but instead of calling
44
+ # +decompile+, you will need to call <tt>Sinatra::Decompile.decompile</tt>.
45
+ #
46
+ module Decompile
47
+ extend self
48
+
49
+ ##
50
+ # Regenerates a string pattern for a given route
51
+ #
52
+ # Example:
53
+ #
54
+ # class Sinatra::Application
55
+ # routes.each do |verb, list|
56
+ # puts "#{verb}:"
57
+ # list.each do |data|
58
+ # puts "\t" << decompile(data)
59
+ # end
60
+ # end
61
+ # end
62
+ #
63
+ # Will return the internal Regexp if unable to reconstruct the pattern,
64
+ # which likely indicates that a Regexp was used in the first place.
65
+ #
66
+ # You can also use this to check whether you could actually use a string
67
+ # pattern instead of your regexp:
68
+ #
69
+ # decompile /^/foo$/ # => '/foo'
70
+ def decompile(pattern, keys = nil, *)
71
+ # Everything in here is basically just the reverse of
72
+ # Sinatra::Base#compile
73
+ pattern, keys = pattern if pattern.respond_to? :to_ary
74
+ keys, str = keys.try(:dup), pattern.inspect
75
+ return pattern unless str.start_with? '/' and str.end_with? '/'
76
+ str.gsub! /^\/\^?|\$?\/$/, ''
77
+ str.gsub! encoded(' '), ' '
78
+ return pattern if str =~ /^[\.\+]/
79
+ str.gsub! /\([^\(\)]*\)/ do |part|
80
+ case part
81
+ when '(.*?)'
82
+ return pattern if keys.shift != 'splat'
83
+ '*'
84
+ when '([^\/?#]+)'
85
+ return pattern if keys.empty?
86
+ ":" << keys.shift
87
+ when /^\(\?\:\\?(.)\|/
88
+ char = $1
89
+ return pattern unless encoded(char) == part
90
+ Regexp.escape(char)
91
+ else
92
+ return pattern
93
+ end
94
+ end
95
+ str.gsub /(.)([\.\+\(\)\/])/ do
96
+ return pattern if $1 != "\\"
97
+ $2
98
+ end
99
+ end
100
+
101
+ private
102
+
103
+ def encoded(char)
104
+ return super if defined? super
105
+ enc = URI.encode(char)
106
+ enc = "(?:#{Regexp.escape enc}|#{URI.encode char, /./})" if enc == char
107
+ enc = "(?:#{enc}|#{encoded('+')})" if char == " "
108
+ enc
109
+ end
110
+ end
111
+
112
+ register Decompile
113
+ end
@@ -0,0 +1,96 @@
1
+ require 'sinatra/base'
2
+
3
+ module Sinatra
4
+ module EngineTracking
5
+ attr_reader :current_engine
6
+
7
+ def erb?
8
+ @current_engine == :erb
9
+ end
10
+
11
+ def erubis?
12
+ @current_engine == :erubis or
13
+ erb? && Tilt[:erb] == Tilt::ErubisTemplate
14
+ end
15
+
16
+ def haml?
17
+ @current_engine == :haml
18
+ end
19
+
20
+ def sass?
21
+ @current_engine == :sass
22
+ end
23
+
24
+ def scss?
25
+ @current_engine == :scss
26
+ end
27
+
28
+ def less?
29
+ @current_engine == :less
30
+ end
31
+
32
+ def builder?
33
+ @current_engine == :builder
34
+ end
35
+
36
+ def liquid?
37
+ @current_engine == :liquid
38
+ end
39
+
40
+ def markdown?
41
+ @current_engine == :markdown
42
+ end
43
+
44
+ def textile?
45
+ @current_engine == :textile
46
+ end
47
+
48
+ def rdoc?
49
+ @current_engine == :rdoc
50
+ end
51
+
52
+ def radius?
53
+ @current_engine == :radius
54
+ end
55
+
56
+ def markaby?
57
+ @current_engine == :markaby
58
+ end
59
+
60
+ def coffee?
61
+ @current_engine == :coffee
62
+ end
63
+
64
+ def nokogiri?
65
+ @current_engine == :nokogiri
66
+ end
67
+
68
+ def slim?
69
+ @current_engine == :slim
70
+ end
71
+
72
+ def creole?
73
+ @current_engine == :creole
74
+ end
75
+
76
+ def initialize(*)
77
+ @current_engine = :ruby
78
+ super
79
+ end
80
+
81
+ def with_engine(engine)
82
+ @current_engine, engine_was = engine.to_sym, @current_engine
83
+ yield
84
+ ensure
85
+ @current_engine = engine_was
86
+ end
87
+
88
+ private
89
+
90
+ def render(engine, *)
91
+ with_engine(engine) { super }
92
+ end
93
+ end
94
+
95
+ helpers EngineTracking
96
+ end
@@ -0,0 +1,95 @@
1
+ require 'sinatra/base'
2
+ require 'backports/basic_object' unless defined? BasicObject
3
+
4
+ module Sinatra
5
+
6
+ # = Sinatra::Extension
7
+ #
8
+ # <tt>Sinatra::Extension</tt> is a mixin that provides some syntactic sugar
9
+ # for your extensions. It allows you to call directly inside your extension
10
+ # module almost any <tt>Sinatra::Base</tt> method. This means you can use
11
+ # +get+ to define a route, +before+ to define a before filter, +set+ to
12
+ # define a setting, a so on.
13
+ #
14
+ # Is important to be aware that this mixin remembers the methods calls you
15
+ # make, and then, when your extension is registered, replays them on the
16
+ # Sinatra application that has been extended. In order to do that, it
17
+ # defines a <tt>registered</tt> method, so, if your extension defines one
18
+ # too, remember to call +super+.
19
+ #
20
+ # == Usage
21
+ #
22
+ # Just require the mixin and extend your extension with it:
23
+ #
24
+ # require 'sinatra/extension'
25
+ #
26
+ # module MyExtension
27
+ # extend Sinatra::Extension
28
+ #
29
+ # # set some settings for development
30
+ # configure :development do
31
+ # set :reload_stuff, true
32
+ # end
33
+ #
34
+ # # define a route
35
+ # get '/' do
36
+ # 'Hello World'
37
+ # end
38
+ #
39
+ # # The rest of your extension code goes here...
40
+ # end
41
+ #
42
+ # You can also create an extension with the +new+ method:
43
+ #
44
+ # MyExtension = Sinatra::Extension.new do
45
+ # # Your extension code goes here...
46
+ # end
47
+ #
48
+ # This is useful when you just want to pass a block to
49
+ # <tt>Sinatra::Base.register</tt>.
50
+ module Extension
51
+ def self.new(&block)
52
+ ext = Module.new.extend(self)
53
+ ext.class_eval(&block)
54
+ ext
55
+ end
56
+
57
+ def settings
58
+ self
59
+ end
60
+
61
+ def configure(*args, &block)
62
+ record(:configure, *args) { |c| c.instance_exec(c, &block) }
63
+ end
64
+
65
+ def registered(base = nil, &block)
66
+ base ? replay(base) : record(:class_eval, &block)
67
+ end
68
+
69
+ private
70
+
71
+ def record(method, *args, &block)
72
+ recorded_methods << [method, args, block]
73
+ end
74
+
75
+ def replay(object)
76
+ recorded_methods.each { |m, a, b| object.send(m, *a, &b) }
77
+ end
78
+
79
+ def recorded_methods
80
+ @recorded_methods ||= []
81
+ end
82
+
83
+ def method_missing(method, *args, &block)
84
+ return super unless Sinatra::Base.respond_to? method
85
+ record(method, *args, &block)
86
+ DontCall.new(method)
87
+ end
88
+
89
+ class DontCall < BasicObject
90
+ def initialize(method) @method = method end
91
+ def method_missing(*) fail "not supposed to use result of #@method!" end
92
+ def inspect; "#<#{self.class}: #{@method}>" end
93
+ end
94
+ end
95
+ end