sinatra-bind 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a615b6b16da64b73b4d395f04147811c80ffba3
4
+ data.tar.gz: a8fb7f8e65c7d70bc4baa72e944b37151cc4ef11
5
+ SHA512:
6
+ metadata.gz: 5d6eba1c68520c0ba2259b2ef701eda4ecadeb5ba13f01c979d870e0c9c900446ce7a66f0f638f4f14e3ae52b5444bfcf175bc8e55e45a94c0bbe1e78dd72890
7
+ data.tar.gz: df0d55386c2304f1232edc80d69a9fa9e03f17ebd42f1500df2387c2e9be4016c9b3526a569d9bd5cbd9746c95c1c7fd57f353b49242f5da6e1d8717eec16ce4
data/.gitignore ADDED
@@ -0,0 +1,22 @@
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
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ lang: ruby
2
+ before_install: gem install bundler --pre
3
+ install:
4
+ - gem update --system
5
+ - bundle update
6
+ rvm:
7
+ - 2.0.0
8
+ - 2.1.0
9
+ - jruby-head
10
+ - rbx
11
+ notifications:
12
+ recipients:
13
+ - namusyaka@gmail.com
14
+ branches:
15
+ only:
16
+ - master
17
+ matrix:
18
+ allow_failures:
19
+ - rvm: rbx
20
+ - rvm: jruby-head
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in sinatra-bind.gemspec
4
+ gemspec
5
+
6
+ gem 'sinatra'
7
+ gem 'rack-test'
8
+ gem 'minitest'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 namusyaka
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,76 @@
1
+ # Sinatra::Bind
2
+
3
+ [![Build Status](https://travis-ci.org/namusyaka/sinatra-bind.svg)](https://travis-ci.org/namusyaka/sinatra-bind)
4
+
5
+ Binds instance method to routes.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'sinatra-bind'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install sinatra-bind
20
+
21
+ ## Usage
22
+
23
+ You can define a route without block smoothly.
24
+
25
+ ```ruby
26
+ class App < Sinatra::Base
27
+ register Sinatra::Bind
28
+
29
+ def index
30
+ "hello world"
31
+ end
32
+
33
+ on "/", to: :index
34
+ end
35
+ ```
36
+
37
+ If specified the :type option, it will be used as request method.
38
+
39
+ ```ruby
40
+ class App < Sinatra::Base
41
+ register Sinatra::Bind
42
+
43
+ def index
44
+ "hello world"
45
+ end
46
+
47
+ on "/", to: :index, type: :post
48
+ end
49
+ ```
50
+
51
+ If passed `:before` or `:after` inn the `:type` option, it will be added as the filters.
52
+
53
+ ```ruby
54
+ class App < Sinatra::Base
55
+ register Sinatra::Bind
56
+
57
+ def before_index
58
+ @foo = "bob"
59
+ end
60
+
61
+ def index
62
+ "hello #{@foo}"
63
+ end
64
+
65
+ on "/", to: :before_index, type: :before
66
+ on "/", to: :index
67
+ end
68
+ ```
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it ( https://github.com/namusyaka/sinatra-bind/fork )
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << "test"
6
+ test.test_files = Dir['test/*_test.rb']
7
+ test.verbose = true
8
+ end
9
+ task default: :test
10
+
@@ -0,0 +1 @@
1
+ require 'sinatra/bind'
@@ -0,0 +1,87 @@
1
+ require "sinatra/bind/version"
2
+
3
+ module Sinatra
4
+ module Bind
5
+ # Sinatra::Bind enables to define a route by using instance method.
6
+ # In other words, you can define a route without block.
7
+ #
8
+ # @example
9
+ # module AwesomeMethods
10
+ # def before_article
11
+ # @ex = params['id'] * "!"
12
+ # end
13
+ #
14
+ # def find_article(id)
15
+ # "Article##{id} #{@ex}"
16
+ # end
17
+ # end
18
+ #
19
+ # class App < Sinatra::Base
20
+ # include AwesomeMethods
21
+ #
22
+ # def index
23
+ # "hello world"
24
+ # end
25
+ #
26
+ # on "/", to: :index
27
+ #
28
+ # on "/articles/:id", to: :before_article, type: :before
29
+ # on "/articles/:id", to: :find_article
30
+ # end
31
+ def self.registered(app)
32
+ app.extend ClassMethods
33
+ end
34
+
35
+ module ClassMethods
36
+ FILTER_NAMES = ['BEFORE', 'AFTER'].freeze
37
+
38
+ # Defines a route without block smoothly
39
+ # @param [String] path
40
+ # @option [String, Symbol] :to The method name that must be defined as instance method.
41
+ # @option [String, Symbol] :type The verb means REQUEST_METHOD, also can be received as filter names.
42
+ def on(path, options = {})
43
+ verb = (options.delete(:type) || 'GET').to_s.upcase
44
+ return bound_filter(verb, path, options) if FILTER_NAMES.include?(verb)
45
+ method_name = options.delete(:to)
46
+ process_bound_route(verb, path, method_name) do
47
+ method = instance_method(method_name)
48
+ bound_route(verb, path, options.merge(method_name: "#{verb} #{method_name}"), method)
49
+ end
50
+ end
51
+
52
+ def bound_route(verb, path, options, method)
53
+ host_name(options.delete(:host)) if options.key?(:host)
54
+ signature = compile_bound_route!(verb, path, method, options)
55
+ (@routes[verb] ||= []) << signature
56
+ invoke_hook(:route_added, verb, path, method)
57
+ signature
58
+ end
59
+
60
+ def bound_filter(type, path, options)
61
+ path, options = //, path if path.respond_to?(:each_pair)
62
+ method = instance_method(options.delete(:to))
63
+ filters[type.downcase.to_sym] << compile_bound_route!(type, path || //, method, options)
64
+ end
65
+
66
+ def compile_bound_route!(verb, path, unbound_method, options)
67
+ method_name = options.delete(:method_name)
68
+ options.each_pair { |option, args| send(option, *args) }
69
+ pattern, keys = compile path
70
+ conditions, @conditions = @conditions, []
71
+ wrapper = unbound_method.arity != 0 ?
72
+ proc { |a,p| unbound_method.bind(a).call(*p) } :
73
+ proc { |a,p| unbound_method.bind(a).call }
74
+ wrapper.instance_variable_set(:@route_name, method_name)
75
+ [ pattern, keys, conditions, wrapper ]
76
+ end
77
+
78
+ def process_bound_route(verb, path, method_name)
79
+ return yield unless verb == 'GET'
80
+ conditions = @conditions.dup; yield; @conditions = conditions
81
+ on path, to: method_name, type: 'HEAD'
82
+ end
83
+
84
+ private :bound_route, :bound_filter, :compile_bound_route!, :process_bound_route
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,5 @@
1
+ module Sinatra
2
+ module Bind
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'sinatra/bind/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "sinatra-bind"
8
+ spec.version = Sinatra::Bind::VERSION
9
+ spec.authors = ["namusyaka"]
10
+ spec.email = ["namusyaka@gmail.com"]
11
+ spec.summary = %q{Binds instance method on routes}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/namusyaka/sinatra-bind"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
data/test/bind_test.rb ADDED
@@ -0,0 +1,86 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+ require 'helper'
3
+
4
+ describe Sinatra::Bind do
5
+ describe "basic usage" do
6
+ it "can define a route" do
7
+ mock_app do
8
+ def hello; "Hello World" end
9
+ on "/", to: :hello
10
+ end
11
+ get '/'
12
+ assert_equal 'Hello World', last_response.body
13
+ end
14
+
15
+ it "can define a route correctly even if path contains named params" do
16
+ mock_app do
17
+ def show(id, type); "id: #{id}, type: #{type}" end
18
+ on "/show/:id/:type", to: :show
19
+ end
20
+ get '/show/1234/frank'
21
+ assert_equal 'id: 1234, type: frank', last_response.body
22
+ end
23
+
24
+ it "should support instance variable sharing" do
25
+ mock_app do
26
+ before("/foo"){ @a = "hey" }
27
+ def hey; @a end
28
+ on "/foo", to: :hey
29
+ end
30
+ get '/foo'
31
+ assert_equal 'hey', last_response.body
32
+ end
33
+
34
+ it "can define a filter" do
35
+ mock_app do
36
+ def bar; @b = "bar" end
37
+ def show_bar; @b end
38
+ on "/bar", to: :bar, type: :before
39
+ on "/bar", to: :show_bar
40
+ end
41
+ get '/bar'
42
+ assert_equal 'bar', last_response.body
43
+ end
44
+ end
45
+
46
+ describe "compatbility with sinatra" do
47
+ it "can use route options" do
48
+ mock_app do
49
+ require 'json'
50
+ def hello; JSON.dump(:a => "b") end
51
+ on "/", to: :hello, provides: :json
52
+ end
53
+ get "/"
54
+ assert_equal "application/json", last_response.headers["Content-Type"]
55
+ assert_equal '{"a":"b"}', last_response.body
56
+ end
57
+
58
+ it "should add the HEAD route if the GET route is added" do
59
+ mock_app do
60
+ def hello; "hello world" end
61
+ on "/", to: :hello
62
+ end
63
+ head "/"
64
+ assert_equal 200, last_response.status
65
+ end
66
+
67
+ it "should invoke the :route_added hook when route is added" do
68
+ module RouteAddedTest
69
+ @routes, @procs = [], []
70
+ def self.routes ; @routes ; end
71
+ def self.procs ; @procs ; end
72
+ def self.route_added(verb, path, proc)
73
+ @routes << [verb, path]
74
+ @procs << proc
75
+ end
76
+ end
77
+ app = mock_app do
78
+ register RouteAddedTest
79
+ def hello; "hello world" end
80
+ on "/", to: :hello
81
+ end
82
+ assert_equal RouteAddedTest.routes, [["GET", "/"], ["HEAD", "/"]]
83
+ assert_equal RouteAddedTest.procs, [app.send(:instance_method, :hello)] * 2
84
+ end
85
+ end
86
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/spec'
3
+ require 'rack/test'
4
+ require 'sinatra/base'
5
+ require 'sinatra/bind'
6
+
7
+ class Sinatra::Base
8
+ include MiniTest::Assertions
9
+ register Sinatra::Bind
10
+ end
11
+
12
+ class MiniTest::Spec
13
+ include Rack::Test::Methods
14
+
15
+ class << self
16
+ alias context describe
17
+ end
18
+
19
+ def app
20
+ Rack::Lint.new(@app)
21
+ end
22
+
23
+ def mock_app(base = Sinatra::Base, &block)
24
+ @app = Sinatra.new(base, &block)
25
+ @app.set :logging, false
26
+ end
27
+ end
28
+
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sinatra-bind
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - namusyaka
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Binds instance method on routes
42
+ email:
43
+ - namusyaka@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - .gitignore
49
+ - .travis.yml
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/sinatra-bind.rb
55
+ - lib/sinatra/bind.rb
56
+ - lib/sinatra/bind/version.rb
57
+ - sinatra-bind.gemspec
58
+ - test/bind_test.rb
59
+ - test/helper.rb
60
+ homepage: https://github.com/namusyaka/sinatra-bind
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.0.14
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Binds instance method on routes
84
+ test_files:
85
+ - test/bind_test.rb
86
+ - test/helper.rb
87
+ has_rdoc: