nancy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in nancy.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Guillermo Iguaran
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Nancy
2
+ _Sinatra's little daughter_
3
+
4
+ ![Frank and Nancy by classic film scans](http://farm6.staticflickr.com/5212/5386187897_e3155cec68.jpg)
5
+
6
+ ## Description
7
+
8
+ Minimal Ruby microframework for web development inspired in [Sinatra](http://www.sinatrarb.com/)
9
+
10
+ ## Installation
11
+
12
+ Install the gem:
13
+
14
+ $ gem install nancy
15
+
16
+ or add it to your Gemfile:
17
+
18
+ gem "nancy"
19
+
20
+ ## Usage
21
+
22
+ Here's a simple application:
23
+
24
+ ```ruby
25
+ # hello.rb
26
+ require "nancy"
27
+
28
+ class Hello < Nancy::Base
29
+ use Rack::Session::Cookie
30
+
31
+ get "/" do
32
+ "Hello World"
33
+ end
34
+
35
+ get "/hello" do
36
+ redirect "/"
37
+ end
38
+
39
+ get "/hello/:name" do
40
+ "Hello #{params['name']}"
41
+ end
42
+
43
+ post "/hello" do
44
+ "Hello #{params['name']}"
45
+ end
46
+
47
+ get "/template" do
48
+ @message = "Hello world"
49
+ render("views/hello.erb")
50
+ end
51
+ end
52
+ ```
53
+
54
+ To run it, you can create a `config.ru` file:
55
+
56
+ ``` ruby
57
+ # config.ru
58
+ require "./hello"
59
+
60
+ run App.new
61
+ ```
62
+
63
+ You can now run `rackup` and enjoy what you have just created.
64
+
65
+ Check examples folder for a detailed example.
66
+
67
+ ## Contributing
68
+
69
+ 1. Fork it
70
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
71
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
72
+ 4. Push to the branch (`git push origin my-new-feature`)
73
+ 5. Create new Pull Request
74
+
75
+
76
+ ## Copyright
77
+
78
+ Copyright (c) 2012 Guillermo Iguaran. See LICENSE for
79
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env rake
2
+
3
+ task :test do
4
+ Dir.chdir('test'){ ruby('base_test.rb') }
5
+ end
6
+
7
+ task :default => :test
data/examples/app.rb ADDED
@@ -0,0 +1,64 @@
1
+ $:.push File.expand_path("../../lib", __FILE__)
2
+
3
+ require "nancy/base"
4
+
5
+ class App < Nancy::Base
6
+ use Rack::Runtime
7
+ use Rack::Session::Cookie
8
+ use Rack::Static, :urls => ["/javascripts"], :root => "public"
9
+
10
+ get "/" do
11
+ "Hello World"
12
+ end
13
+
14
+ get "/hello/:name" do
15
+ "Hello #{params['name']}"
16
+ end
17
+
18
+ get "/:message/:name" do
19
+ @message = params['message']
20
+ @name = params['name']
21
+ render "hello.erb"
22
+ end
23
+
24
+ post "/params/:params" do
25
+ "#{params}"
26
+ end
27
+
28
+ get "/redirect" do
29
+ session["test"] = "test"
30
+ redirect "/session"
31
+ end
32
+
33
+ get "/session" do
34
+ "#{session['test']}"
35
+ end
36
+
37
+ get "/set_session" do
38
+ session["test"] = "test 2"
39
+ end
40
+
41
+ patch "/test" do
42
+ "PATCH verb supported"
43
+ end
44
+
45
+ get "/layout" do
46
+ @message = "Hola"
47
+ @name = "Usuario"
48
+ render("layout.erb") { render("hello.erb") }
49
+ end
50
+
51
+ get "/halt/404" do
52
+ halt 404
53
+ end
54
+
55
+ get "/halt_error" do
56
+ halt 500, "Error fatal"
57
+ end
58
+
59
+ # Helper method
60
+ def self.render(*args)
61
+ args[0] = "views/#{args[0]}"
62
+ super(*args)
63
+ end
64
+ end
@@ -0,0 +1,3 @@
1
+ require "./app"
2
+
3
+ run App.new
@@ -0,0 +1 @@
1
+ alert("test")
@@ -0,0 +1 @@
1
+ <%= @message %> <%= @name %>
@@ -0,0 +1,5 @@
1
+ <html>
2
+ <body>
3
+ <%= yield %>
4
+ </body>
5
+ </html>
data/lib/nancy.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'nancy/base'
2
+ require 'nancy/version'
3
+
4
+ module Nancy
5
+ end
data/lib/nancy/base.rb ADDED
@@ -0,0 +1,100 @@
1
+ require 'rack'
2
+ require 'tilt'
3
+
4
+ module Nancy
5
+ class Base
6
+ class << self
7
+ %w(GET POST PATCH PUT DELETE).each do |verb|
8
+ define_method(verb.downcase) do |pattern, &block|
9
+ route_set[verb] << [compile(pattern), block]
10
+ end
11
+ end
12
+ end
13
+
14
+ def self.compile(pattern)
15
+ keys = []
16
+ pattern.gsub!(/(:\w+)/) do |match|
17
+ keys << $1[1..-1]
18
+ "([^/?#]+)"
19
+ end
20
+ [%r{^#{pattern}$}, keys]
21
+ end
22
+
23
+ def self.route_set
24
+ @route_set ||= Hash.new { |h, k| h[k] = [] }
25
+ end
26
+
27
+ class << self
28
+ %w(request response params).each do |accessor|
29
+ define_method(accessor){ Thread.current[accessor.to_sym] }
30
+ end
31
+ end
32
+
33
+ def self.session
34
+ request.env["rack.session"]
35
+ end
36
+
37
+ def self.redirect(uri)
38
+ halt 302, {"Location" => uri}
39
+ end
40
+
41
+ def self.use(middleware, *args, &block)
42
+ middlewares << [middleware, *args, block]
43
+ end
44
+
45
+ def self.middlewares
46
+ @middlewares ||= []
47
+ end
48
+
49
+ def initialize
50
+ klass = self.class
51
+ @app = Rack::Builder.new do
52
+ klass.middlewares.each do |middleware|
53
+ middleware, *args, block = middleware
54
+ use(middleware, *args, &block)
55
+ end
56
+ run klass
57
+ end
58
+ end
59
+
60
+ def call(env)
61
+ @app.call(env)
62
+ end
63
+
64
+ def self.call(env)
65
+ Thread.current[:request] = Rack::Request.new(env)
66
+ Thread.current[:response] = Rack::Response.new
67
+ Thread.current[:params] = request.params
68
+ response = catch(:halt) do
69
+ route_eval(request.request_method, request.path_info)
70
+ end.finish
71
+ end
72
+
73
+ def self.route_eval(request_method, path_info)
74
+ route_set[request_method].each do |matcher, block|
75
+ if match = path_info.match(matcher[0])
76
+ if (captures = match.captures) && !captures.empty?
77
+ url_params = Hash[*matcher[1].zip(captures).flatten]
78
+ Thread.current[:params] = url_params.merge(params)
79
+ end
80
+ response.write(block.call)
81
+ halt response
82
+ end
83
+ end
84
+ halt 404
85
+ end
86
+
87
+ def self.halt(*res)
88
+ throw :halt, res.first if res.first.is_a?(Rack::Response)
89
+ response.status = res.select{|x| x.is_a?(Fixnum)}.first || 200
90
+ headers = res.select{|x| x.is_a?(Hash)}.first || {}
91
+ response.header.merge!(headers)
92
+ response.body = [(res.select{|x| x.is_a?(String)}.first || "")]
93
+ throw :halt, response
94
+ end
95
+
96
+ def self.render(template, locals = {}, options = {}, &block)
97
+ Tilt.new(template).render(self, locals, &block)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,3 @@
1
+ module Nancy
2
+ VERSION = "0.0.1"
3
+ end
data/nancy.gemspec ADDED
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/nancy/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Guillermo Iguaran"]
6
+ gem.email = ["guilleiguaran@gmail.com"]
7
+ gem.description = %q{Sinatra's little daughter}
8
+ gem.summary = %q{Ruby Microframework inspired in Sinatra}
9
+ gem.homepage = "https://github.com/guilleiguaran/nancy"
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "nancy"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Nancy::VERSION
17
+
18
+ gem.add_dependency 'rack'
19
+ gem.add_dependency 'tilt'
20
+ gem.add_development_dependency 'minitest'
21
+ gem.add_development_dependency 'rack-test'
22
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,102 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+ require "minitest/autorun"
3
+
4
+ class BaseTest < MiniTest::Unit::TestCase
5
+ include Rack::Test::Methods
6
+
7
+ class TestApp < Nancy::Base
8
+ get "/" do
9
+ "Hello World"
10
+ end
11
+
12
+ get "/hello/:name" do
13
+ "Hello #{params['name']}"
14
+ end
15
+
16
+ post "/hello" do
17
+ "Hello #{params['name']}"
18
+ end
19
+
20
+ get "/hello" do
21
+ "Hello #{params['name']}"
22
+ end
23
+
24
+ get "/redirect" do
25
+ redirect "/destination"
26
+ end
27
+
28
+ get "/destination" do
29
+ "Redirected from /redirect"
30
+ end
31
+
32
+ get "/halting" do
33
+ halt 500, "Internal Error"
34
+ "not reached code"
35
+ end
36
+
37
+ get "/view" do
38
+ @message = "Hello from view"
39
+ render("#{view_path}/view.erb")
40
+ end
41
+
42
+ get "/layout" do
43
+ @message = "Hello from view"
44
+ render("#{view_path}/layout.erb") { render("#{view_path}/view.erb") }
45
+ end
46
+
47
+ def self.view_path
48
+ File.expand_path("fixtures", Dir.pwd)
49
+ end
50
+ end
51
+
52
+ def app
53
+ TestApp
54
+ end
55
+
56
+ def test_app_respond_with_call
57
+ assert TestApp.respond_to?(:call)
58
+ request = Rack::MockRequest.new(TestApp)
59
+ response = request.get('/')
60
+ assert_equal 200, response.status
61
+ assert_equal 'Hello World', response.body
62
+ end
63
+
64
+ def test_url_params
65
+ get '/hello/user'
66
+ assert_equal 'Hello user', last_response.body
67
+ end
68
+
69
+ def test_post_params
70
+ post '/hello', :name => 'bob'
71
+ assert_equal 'Hello bob', last_response.body
72
+ end
73
+
74
+ def test_query_params
75
+ get '/hello?name=foo'
76
+ assert_equal 'Hello foo', last_response.body
77
+ end
78
+
79
+ def test_redirect
80
+ get '/redirect'
81
+ follow_redirect!
82
+ assert last_response.body.include?('Redirected')
83
+ end
84
+
85
+ def test_halting
86
+ get '/halting'
87
+ assert 500, last_response.status
88
+ assert_equal 'Internal Error', last_response.body
89
+ end
90
+
91
+ def test_render
92
+ get '/view'
93
+ assert !last_response.body.include?("<html>")
94
+ assert last_response.body.include?("Hello from view")
95
+ end
96
+
97
+ def test_render_with_layout
98
+ get '/layout'
99
+ assert last_response.body.include?("<html>")
100
+ assert last_response.body.include?("Hello from view")
101
+ end
102
+ end
@@ -0,0 +1,7 @@
1
+ <!doctype html>
2
+ <html>
3
+ <head></head>
4
+ <body>
5
+ <%= yield %>
6
+ </body>
7
+ </html>
@@ -0,0 +1 @@
1
+ <%= @message %>
@@ -0,0 +1,10 @@
1
+ testdir = File.dirname(__FILE__)
2
+ $LOAD_PATH.unshift testdir unless $LOAD_PATH.include?(testdir)
3
+
4
+ libdir = File.dirname(File.dirname(__FILE__)) + '/lib'
5
+ $LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
6
+
7
+ require "rubygems"
8
+ require "nancy"
9
+ require "minitest/unit"
10
+ require "rack/test"
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nancy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Guillermo Iguaran
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &70255892249720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70255892249720
25
+ - !ruby/object:Gem::Dependency
26
+ name: tilt
27
+ requirement: &70255892249040 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70255892249040
36
+ - !ruby/object:Gem::Dependency
37
+ name: minitest
38
+ requirement: &70255892248380 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70255892248380
47
+ - !ruby/object:Gem::Dependency
48
+ name: rack-test
49
+ requirement: &70255892247960 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70255892247960
58
+ description: Sinatra's little daughter
59
+ email:
60
+ - guilleiguaran@gmail.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE
68
+ - README.md
69
+ - Rakefile
70
+ - examples/app.rb
71
+ - examples/config.ru
72
+ - examples/public/js/test.js
73
+ - examples/views/hello.erb
74
+ - examples/views/layout.erb
75
+ - lib/nancy.rb
76
+ - lib/nancy/base.rb
77
+ - lib/nancy/version.rb
78
+ - nancy.gemspec
79
+ - test/base_test.rb
80
+ - test/fixtures/layout.erb
81
+ - test/fixtures/view.erb
82
+ - test/test_helper.rb
83
+ homepage: https://github.com/guilleiguaran/nancy
84
+ licenses: []
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubyforge_project:
103
+ rubygems_version: 1.8.17
104
+ signing_key:
105
+ specification_version: 3
106
+ summary: Ruby Microframework inspired in Sinatra
107
+ test_files:
108
+ - test/base_test.rb
109
+ - test/fixtures/layout.erb
110
+ - test/fixtures/view.erb
111
+ - test/test_helper.rb