sinatra-sugar 0.4.0.a

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,46 @@
1
+ Sinatra::Sugar
2
+ ==============
3
+
4
+ Basic [Sinatra](http://sinatrarb.com) extension (mainly extending Sinatra's standard methods, like set or register).
5
+ Also it features a more advanced path guessing than Sinatra::Base.
6
+
7
+ Normally you do not have to register this module manually, as the other extensions will do so if necessary.
8
+
9
+ BigBand
10
+ -------
11
+
12
+ Sinatra::Sugar is part of the [BigBand](http://github.com/rkh/big_band) stack.
13
+ Check it out if you are looking for other fancy Sinatra extensions.
14
+
15
+ More advanced set
16
+ -----------------
17
+
18
+ - Adds set\_#{key} and set_value hooks to set.
19
+ - Merges the old value with the new one, if both are hashes:
20
+
21
+ set :haml, :format => :html5, :escape_html => true
22
+ set :haml, :excape_html => false
23
+ haml # => { :format => :html5, :escape_html => false }
24
+
25
+ - Allowes passing a block:
26
+
27
+ set(:foo) { Time.now }
28
+
29
+ - Defines a helper to access #{key} and #{key}? unless a helper/method with that name already exists.
30
+
31
+ More advanced register
32
+ ----------------------
33
+
34
+ If an exntesion is registered twice, the registered hook will only be called once.
35
+
36
+ Ability to extend command line options
37
+ --------------------------------------
38
+
39
+ Example:
40
+
41
+ require "sinatra"
42
+ require "sinatra/sugar"
43
+
44
+ configure do
45
+ run_option_parser.on("-i") { puts "yes, -i is a nice option" }
46
+ end
@@ -0,0 +1,188 @@
1
+ require "sinatra/base"
2
+ require "monkey"
3
+
4
+ module Sinatra
5
+ module Sugar
6
+ module BaseMethods
7
+ Base.extend self
8
+
9
+ def callers_to_ignore
10
+ class << Sinatra::Base
11
+ CALLERS_TO_IGNORE
12
+ end
13
+ end
14
+
15
+ def ignore_caller(pattern = nil)
16
+ case pattern
17
+ when String then Dir.glob(pattern) { |file| ignore_caller File.expand_path(file).to_sym }
18
+ when Symbol then ignore_caller Regexp.new(Regexp.escape(pattern.to_s))
19
+ when Regexp then callers_to_ignore << pattern
20
+ when nil then ignore_caller caller.first[/^[^:]*/].to_sym
21
+ when Array then pattern.each { |p| ignore_caller p }
22
+ else raise ArgumentError, "cannot handle #{pattern.inspect}"
23
+ end
24
+ end
25
+ end
26
+
27
+ module ClassMethods
28
+
29
+ attr_writer :root, :guessed_root
30
+
31
+ # More advanced set:
32
+ # - Adds set_#{key} and set_value hooks to set.
33
+ # - Merges the old value with the new one, if both are hashes:
34
+ # set :haml, :format => :html5, :escape_html => true
35
+ # set :haml, :excape_html => false
36
+ # haml # => { :format => :html5, :escape_html => false }
37
+ # - Allowes passing a block:
38
+ # set(:foo) { Time.now }
39
+ # - Defines a helper to access #{key} and #{key}? unless a helper/method with that name already exists.
40
+ def set(key, value = self, &block)
41
+ # FIXME: refactor, refactor, refactor
42
+ if block_given?
43
+ raise ArgumentError, "both a value and a block given" if value != self
44
+ value = block
45
+ end
46
+ symbolized = (key.to_sym if key.respond_to? :to_sym)
47
+ old_value = (send(symbolized) if symbolized and respond_to? symbolized)
48
+ value = old_value.merge value if value.is_a? Hash and old_value.is_a? Hash
49
+ super(key, value)
50
+ if symbolized
51
+ method_names = instance_methods.map { |m| m.to_s }
52
+ define_method(key) { self.class.send(key) } unless method_names.include? key.to_s
53
+ define_method("#{key}?") { self.class.send("#{key}?") } unless method_names.include? "#{key}?"
54
+ end
55
+ # HACK: Sinatra::Base.set uses recursion and in the final step value always
56
+ # is a Proc. Also, if value is a Proc no step ever follows. I abuse this to
57
+ # invoke the hooks only once per set.
58
+ if value.is_a? Proc
59
+ invoke_hook "set_#{key}", self
60
+ invoke_hook :set_value, self, key
61
+ end
62
+ self
63
+ end
64
+
65
+ # More advanced register:
66
+ # - If an exntesion is registered twice, the registered hook will only be called once.
67
+ def register(*extensions, &block)
68
+ extensions.reject! { |e| self.extensions.include? e }
69
+ super(*extensions, &block)
70
+ end
71
+
72
+ # Short hand so you can skip those ugly File.expand_path(File.join(File.dirname(__FILE__), ...))
73
+ # lines.
74
+ def root_path(*args)
75
+ relative = File.join(*args)
76
+ return relative if relative.expand_path == relative
77
+ root.expand_path / relative
78
+ end
79
+
80
+ # Like root_path, but does return an array instead of a string. Optionally takes a block that will
81
+ # be called for each entry once.
82
+ #
83
+ # Example:
84
+ # class Foo < BigBand
85
+ # root_glob("app", "{models,views,controllers}", "*.rb") { |file| load file }
86
+ # end
87
+ def root_glob(*args, &block)
88
+ Dir.glob(root_path(*args), &block)
89
+ end
90
+
91
+ # Whether or not to start a webserver.
92
+ def run?
93
+ @run ||= true
94
+ @run and !@running and app_file? and $0.expand_path == app_file.expand_path
95
+ end
96
+
97
+ # Disable automatically running this class as soon it is subclassed.
98
+ def inherited
99
+ super
100
+ @run = false
101
+ end
102
+
103
+ # The application's root directory. BigBand will guess if missing.
104
+ def root
105
+ return ".".expand_path unless app_file?
106
+ return @root if @root
107
+ @guessed_root ||= begin
108
+ dir = app_file.expand_path.dirname
109
+ if dir.basename == "lib" and not (dir / "lib").directory?
110
+ dir.dirname
111
+ else
112
+ dir
113
+ end
114
+ end
115
+ end
116
+
117
+ # Returns true if the #root is known.
118
+ def root?
119
+ !!@root || app_file?
120
+ end
121
+
122
+ # Option parser for #run!
123
+ def run_option_parser
124
+ @run_option_parser ||= begin
125
+ require 'optparse'
126
+ OptionParser.new do |op|
127
+ op.on('-x') { set :lock, true }
128
+ op.on('-e env') { |val| set :environment, val.to_sym }
129
+ op.on('-s server') { |val| set :server, val }
130
+ op.on('-p port') { |val| set :port, val.to_i }
131
+ end
132
+ end
133
+ end
134
+
135
+ # Extended #run!, offers an extandable option parser for
136
+ # BigBand with the same standard options as the one of
137
+ # Sinatra#Default (see #run_option_parser).
138
+ def run!(options = {})
139
+ run_option_parser.parse!(ARGV.dup) unless ARGV.empty?
140
+ @running = true
141
+ super(options)
142
+ end
143
+
144
+ end
145
+
146
+ module InstanceMethods
147
+
148
+ # See BigBand::BasicExtentions::ClassMethods#root_path
149
+ def root_path(*args)
150
+ self.class.root_path(*args)
151
+ end
152
+
153
+ # See BigBand::BasicExtentions::ClassMethods#root_path
154
+ def root_glob(*args, &block)
155
+ self.class.root_glob(*args, &block)
156
+ end
157
+
158
+ # See BigBand::BasicExtentions::ClassMethods#root
159
+ def root
160
+ self.class.root
161
+ end
162
+
163
+ # See BigBand::BasicExtentions::ClassMethods#root?
164
+ def root?
165
+ self.class.root
166
+ end
167
+
168
+ end
169
+
170
+ def self.registered(klass)
171
+ klass.set :app_file, klass.caller_files.first.expand_path unless klass.app_file?
172
+ klass.extend ClassMethods
173
+ klass.send :include, InstanceMethods
174
+ klass.set :haml, :format => :html5, :escape_html => true
175
+ klass.use Rack::Session::Cookie
176
+ klass.enable :sessions
177
+ end
178
+
179
+ def self.set_app_file(klass)
180
+ klass.guessed_root = nil
181
+ end
182
+
183
+ end
184
+
185
+ Base.ignore_caller
186
+ register Sugar
187
+
188
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path(__FILE__ + "/../../spec_helper.rb")
2
+
3
+ describe Sinatra::Sugar do
4
+
5
+ before { app :Sugar }
6
+
7
+ describe "set" do
8
+
9
+ it "adds hooks to Sinatra::Base#set" do
10
+ extension = Module.new
11
+ extension.should_receive(:set_foo).with(app)
12
+ extension.should_receive(:set_value).with(app, :foo)
13
+ app.register extension
14
+ app.set :foo, 42
15
+ end
16
+
17
+ it "allows passing a block" do
18
+ app.set(:foo) { 42 }
19
+ app.foo.should == 42
20
+ end
21
+
22
+ it "merges hash values" do
23
+ app.set :foo, :bar => 42
24
+ app.set :foo, :baz => 23
25
+ app.foo[:bar].should == 42
26
+ app.foo[:baz].should == 23
27
+ end
28
+
29
+ end
30
+
31
+ describe "register" do
32
+ it "registers an extension only once" do
33
+ extension = Module.new
34
+ extension.should_receive(:registered).once.with(app)
35
+ 10.times { app.register extension }
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,3 @@
1
+ require "sinatra/rspec"
2
+ require "sinatra/sugar"
3
+ Sinatra::Base.set :environment, :test
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-sugar
3
+ version: &id001 !ruby/object:Gem::Version
4
+ version: 0.4.0.a
5
+ platform: ruby
6
+ authors:
7
+ - Konstantin Haase
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-15 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: monkey-lib
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - "="
22
+ - *id001
23
+ version:
24
+ - !ruby/object:Gem::Dependency
25
+ name: sinatra-test-helper
26
+ type: :development
27
+ version_requirement:
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "="
31
+ - *id001
32
+ version:
33
+ - !ruby/object:Gem::Dependency
34
+ name: sinatra
35
+ type: :runtime
36
+ version_requirement:
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 0.9.4
42
+ version:
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ type: :development
46
+ version_requirement:
47
+ version_requirements: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.3.0
52
+ version:
53
+ description: Some extensions to the sinatra default behavior (usefull for other Sintatra extensions, part of BigBand).
54
+ email: konstantin.mailinglists@googlemail.com
55
+ executables: []
56
+
57
+ extensions: []
58
+
59
+ extra_rdoc_files: []
60
+
61
+ files:
62
+ - lib/sinatra/sugar.rb
63
+ - spec/sinatra/sugar_spec.rb
64
+ - spec/spec_helper.rb
65
+ - README.md
66
+ has_rdoc: yard
67
+ homepage: http://github.com/rkh/sinatra-sugar
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options: []
72
+
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">"
84
+ - !ruby/object:Gem::Version
85
+ version: 1.3.1
86
+ version:
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.5
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: Some extensions to the sinatra default behavior (usefull for other Sintatra extensions, part of BigBand).
94
+ test_files: []
95
+