sinatra-sugar 0.4.0.a

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.
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
+