knot 0.0.1 → 0.0.2
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/.gitignore +1 -0
- data/Gemfile +6 -8
- data/Gemfile.lock +14 -16
- data/README.md +16 -0
- data/Rakefile +19 -0
- data/TODO +13 -0
- data/gem_version.rb +1 -0
- data/knot.gemspec +2 -3
- data/lib/knot/application.rb +13 -6
- data/lib/knot/application/configuration.rb +13 -0
- data/lib/knot/dispatch/route.rb +1 -1
- data/lib/knot/dispatch/router.rb +13 -9
- data/lib/knot/dispatch/router/context.rb +1 -1
- data/spec/acceptance/acceptance_spec.rb +2 -1
- data/spec/acceptance/test_app.rb +8 -0
- data/spec/knot/dispatch/filter_spec.rb +1 -1
- data/spec/knot/dispatch/router_spec.rb +4 -4
- metadata +8 -18
- data/README +0 -2
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/Gemfile
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
source 'http://rubygems.org'
|
2
2
|
|
3
|
-
gem "rack"
|
4
|
-
gem "rack-protection"
|
5
|
-
gem "yajl-ruby"
|
6
|
-
|
3
|
+
gem "rack", '1.4.1'
|
4
|
+
gem "rack-protection", '1.2.0'
|
7
5
|
|
8
6
|
group :test, :development do
|
9
|
-
gem "rack-test"
|
10
|
-
gem "rspec"
|
11
|
-
gem "rake"
|
12
|
-
gem "unicorn"
|
7
|
+
gem "rack-test", '0.6.1'
|
8
|
+
gem "rspec", '2.11.0'
|
9
|
+
gem "rake", '0.9.2.2'
|
10
|
+
gem "unicorn", '4.3.1'
|
13
11
|
end
|
data/Gemfile.lock
CHANGED
@@ -10,28 +10,26 @@ GEM
|
|
10
10
|
rack (>= 1.0)
|
11
11
|
raindrops (0.10.0)
|
12
12
|
rake (0.9.2.2)
|
13
|
-
rspec (2.
|
14
|
-
rspec-core (~> 2.
|
15
|
-
rspec-expectations (~> 2.
|
16
|
-
rspec-mocks (~> 2.
|
17
|
-
rspec-core (2.
|
18
|
-
rspec-expectations (2.
|
19
|
-
diff-lcs (~> 1.1.
|
20
|
-
rspec-mocks (2.
|
13
|
+
rspec (2.11.0)
|
14
|
+
rspec-core (~> 2.11.0)
|
15
|
+
rspec-expectations (~> 2.11.0)
|
16
|
+
rspec-mocks (~> 2.11.0)
|
17
|
+
rspec-core (2.11.1)
|
18
|
+
rspec-expectations (2.11.3)
|
19
|
+
diff-lcs (~> 1.1.3)
|
20
|
+
rspec-mocks (2.11.3)
|
21
21
|
unicorn (4.3.1)
|
22
22
|
kgio (~> 2.6)
|
23
23
|
rack
|
24
24
|
raindrops (~> 0.7)
|
25
|
-
yajl-ruby (1.1.0)
|
26
25
|
|
27
26
|
PLATFORMS
|
28
27
|
ruby
|
29
28
|
|
30
29
|
DEPENDENCIES
|
31
|
-
rack
|
32
|
-
rack-protection
|
33
|
-
rack-test
|
34
|
-
rake
|
35
|
-
rspec
|
36
|
-
unicorn
|
37
|
-
yajl-ruby
|
30
|
+
rack (= 1.4.1)
|
31
|
+
rack-protection (= 1.2.0)
|
32
|
+
rack-test (= 0.6.1)
|
33
|
+
rake (= 0.9.2.2)
|
34
|
+
rspec (= 2.11.0)
|
35
|
+
unicorn (= 4.3.1)
|
data/README.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Knot
|
2
|
+
True README is coming soon.
|
3
|
+
|
4
|
+
For now, Knot is an early version of creating a very small, lightweight wrapper over Rack for simple HTTP apps
|
5
|
+
|
6
|
+
Currently, it can:
|
7
|
+
|
8
|
+
### route requests
|
9
|
+
* has optional filters that take place before a specified set of requests
|
10
|
+
|
11
|
+
### render ERB templates
|
12
|
+
* it caches templates, even in development, so you'll have to restart your server.
|
13
|
+
|
14
|
+
### render JSON
|
15
|
+
|
16
|
+
### basic HTTP (responses / redirects / headers)
|
data/Rakefile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require './gem_version'
|
2
|
+
|
1
3
|
task :default => ["knot:test"]
|
2
4
|
|
3
5
|
namespace :knot do
|
@@ -12,4 +14,21 @@ namespace :knot do
|
|
12
14
|
Kernel.system("bundle exec rspec")
|
13
15
|
end
|
14
16
|
|
17
|
+
namespace :gem do
|
18
|
+
|
19
|
+
task :gemify => [:build, :deploy]
|
20
|
+
|
21
|
+
desc "Builds Knot's gemspec"
|
22
|
+
task :build do
|
23
|
+
system "gem build knot.gemspec"
|
24
|
+
end
|
25
|
+
|
26
|
+
desc "Deploys the Knot gem to rubygems"
|
27
|
+
task :deploy do
|
28
|
+
system "gem push knot-#{VERSION}"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
15
33
|
end
|
34
|
+
|
data/TODO
ADDED
data/gem_version.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
VERSION = '0.0.2'
|
data/knot.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require '
|
4
|
+
require './gem_version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "knot"
|
8
|
-
gem.version =
|
8
|
+
gem.version = VERSION
|
9
9
|
gem.authors = ["Brian Pratt"]
|
10
10
|
gem.email = ["brian@8thlight.com"]
|
11
11
|
gem.description = "Knot"
|
@@ -19,5 +19,4 @@ Gem::Specification.new do |gem|
|
|
19
19
|
|
20
20
|
gem.add_dependency('rack')
|
21
21
|
gem.add_dependency('rack-protection')
|
22
|
-
gem.add_dependency('yajl-ruby')
|
23
22
|
end
|
data/lib/knot/application.rb
CHANGED
@@ -31,10 +31,12 @@ module Knot
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def call(env)
|
34
|
+
request = Rack::Request.new(env)
|
35
|
+
|
34
36
|
begin
|
35
|
-
route_request(
|
36
|
-
rescue =>
|
37
|
-
|
37
|
+
route_request(request)
|
38
|
+
rescue => err
|
39
|
+
handle_error(request, config._handlers[:internal_error], 500, err)
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -42,10 +44,9 @@ module Knot
|
|
42
44
|
self.class.config
|
43
45
|
end
|
44
46
|
|
45
|
-
def route_request(
|
47
|
+
def route_request(request)
|
46
48
|
config.routers.each do |router|
|
47
49
|
begin
|
48
|
-
request = Rack::Request.new(env)
|
49
50
|
response = router._call!(request)
|
50
51
|
return response.to_rack
|
51
52
|
rescue Knot::Dispatch::NoRouteError
|
@@ -53,7 +54,13 @@ module Knot
|
|
53
54
|
end
|
54
55
|
end
|
55
56
|
|
56
|
-
|
57
|
+
handle_error(request, config._handlers[:not_found], 404)
|
58
|
+
end
|
59
|
+
|
60
|
+
def handle_error(request, handler, status, error = nil)
|
61
|
+
response = Knot::Router.new(request, handler)._call!(error)
|
62
|
+
response.status = status
|
63
|
+
return response.to_rack
|
57
64
|
end
|
58
65
|
end
|
59
66
|
end
|
@@ -3,6 +3,11 @@ module Knot
|
|
3
3
|
class Configuration
|
4
4
|
attr_writer :template_path
|
5
5
|
|
6
|
+
def initialize
|
7
|
+
handle(:not_found) { "Aw snap" }
|
8
|
+
handle(:internal_error) { "Error!?" }
|
9
|
+
end
|
10
|
+
|
6
11
|
def add_router(router)
|
7
12
|
routers << router
|
8
13
|
end
|
@@ -15,6 +20,14 @@ module Knot
|
|
15
20
|
@template_path ||= "templates/"
|
16
21
|
end
|
17
22
|
|
23
|
+
def handle(type, &block)
|
24
|
+
_handlers[type] = Knot::Dispatch::Route.new("", "", "", &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
def _handlers
|
28
|
+
@_handlers ||= {}
|
29
|
+
end
|
30
|
+
|
18
31
|
def finalize!
|
19
32
|
routers.each do |router|
|
20
33
|
router.config.knot_template_home = template_path
|
data/lib/knot/dispatch/route.rb
CHANGED
data/lib/knot/dispatch/router.rb
CHANGED
@@ -10,25 +10,29 @@ module Knot::Dispatch
|
|
10
10
|
extend Knot::Dispatch::Router::API
|
11
11
|
|
12
12
|
def self._call!(request)
|
13
|
-
new(request)._call!
|
13
|
+
new(request, matching_route(request))._call!
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.config
|
17
17
|
@config ||= Knot::Dispatch::Router::Config.new(self)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
def self.matching_route(request)
|
21
|
+
route = config.routes.find { |route| route.match?(request) }
|
22
|
+
raise Knot::Dispatch::NoRouteError, "no route matches #{request.path}" if route.nil?
|
21
23
|
|
22
|
-
|
23
|
-
@request = request
|
24
|
-
@response = Knot::Dispatch::Response.new
|
24
|
+
return route
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
route = _config.routes.find { |route| route.match?(request) }
|
27
|
+
attr_reader :request, :response, :route
|
29
28
|
|
30
|
-
|
29
|
+
def initialize(request, route)
|
30
|
+
@request = request
|
31
|
+
@response = Knot::Dispatch::Response.new
|
32
|
+
@route = route
|
33
|
+
end
|
31
34
|
|
35
|
+
def _call!(error = nil)
|
32
36
|
request.params.merge! Path.path_params(route.path, request)
|
33
37
|
|
34
38
|
blocks = _config.applicable_filters(route).map(&:block)
|
@@ -36,7 +40,7 @@ module Knot::Dispatch
|
|
36
40
|
|
37
41
|
catch(:halt) {
|
38
42
|
blocks.map do |block|
|
39
|
-
result =
|
43
|
+
result = instance_exec error, &block
|
40
44
|
response.body << result if result.is_a?(String)
|
41
45
|
end.last
|
42
46
|
}
|
@@ -20,8 +20,8 @@ describe "basic test for API" do
|
|
20
20
|
|
21
21
|
it "returns 404" do
|
22
22
|
response = request.get "/not_to_be_found"
|
23
|
+
response.body.should == "Didn't find that page."
|
23
24
|
response.status.should == 404
|
24
|
-
response.body.should == "Aw snap"
|
25
25
|
end
|
26
26
|
|
27
27
|
it "redirects" do
|
@@ -42,6 +42,7 @@ describe "basic test for API" do
|
|
42
42
|
context "when an exception is raised" do
|
43
43
|
it "returns 500" do
|
44
44
|
response = request.get "/raise_exception"
|
45
|
+
response.body.should == "Someone committed a merge conflict: whoa nelly!!"
|
45
46
|
response.status.should == 500
|
46
47
|
end
|
47
48
|
end
|
data/spec/acceptance/test_app.rb
CHANGED
@@ -45,6 +45,14 @@ class TestApp < Knot::Application
|
|
45
45
|
configure do |config|
|
46
46
|
config.add_router TestRouter
|
47
47
|
config.template_path = "spec/acceptance/templates"
|
48
|
+
|
49
|
+
config.handle(:not_found) do
|
50
|
+
"Didn't find that page."
|
51
|
+
end
|
52
|
+
|
53
|
+
config.handle(:internal_error) do |error|
|
54
|
+
"Someone committed a merge conflict: #{error.message}"
|
55
|
+
end
|
48
56
|
end
|
49
57
|
end
|
50
58
|
|
@@ -78,14 +78,14 @@ describe Knot::Dispatch::Router do
|
|
78
78
|
|
79
79
|
context "#params" do
|
80
80
|
it "gives access to the request's params" do
|
81
|
-
router = Knot::Dispatch::Router.new(request)
|
81
|
+
router = Knot::Dispatch::Router.new(request, nil)
|
82
82
|
router.params.should == request.params
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
86
|
context "#redirect" do
|
87
87
|
it "sets status and location header" do
|
88
|
-
router = Knot::Dispatch::Router.new(request)
|
88
|
+
router = Knot::Dispatch::Router.new(request, nil)
|
89
89
|
response = catch(:halt) { router.redirect('http://www.google.com') }
|
90
90
|
response.status.should == 302
|
91
91
|
response.headers['Location'].should == "http://www.google.com"
|
@@ -94,7 +94,7 @@ describe Knot::Dispatch::Router do
|
|
94
94
|
|
95
95
|
context "#json" do
|
96
96
|
it "returns the object in json" do
|
97
|
-
router = Knot::Dispatch::Router.new(request)
|
97
|
+
router = Knot::Dispatch::Router.new(request, nil)
|
98
98
|
response = catch(:halt) { router.json(:foo => "bar") }
|
99
99
|
JSON.parse(response.body.first).should == {'foo' => 'bar'}
|
100
100
|
end
|
@@ -102,7 +102,7 @@ describe Knot::Dispatch::Router do
|
|
102
102
|
|
103
103
|
context "#status" do
|
104
104
|
it "sets the status code on the response" do
|
105
|
-
router = Knot::Dispatch::Router.new(request)
|
105
|
+
router = Knot::Dispatch::Router.new(request, nil)
|
106
106
|
router.status(422)
|
107
107
|
router.response.status.should == 422
|
108
108
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -43,22 +43,6 @@ dependencies:
|
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '0'
|
46
|
-
- !ruby/object:Gem::Dependency
|
47
|
-
name: yajl-ruby
|
48
|
-
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
|
-
requirements:
|
51
|
-
- - ! '>='
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '0'
|
54
|
-
type: :runtime
|
55
|
-
prerelease: false
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
46
|
description: Knot
|
63
47
|
email:
|
64
48
|
- brian@8thlight.com
|
@@ -66,13 +50,16 @@ executables: []
|
|
66
50
|
extensions: []
|
67
51
|
extra_rdoc_files: []
|
68
52
|
files:
|
53
|
+
- .gitignore
|
69
54
|
- .rspec
|
70
55
|
- .rvmrc
|
71
56
|
- Gemfile
|
72
57
|
- Gemfile.lock
|
73
|
-
- README
|
58
|
+
- README.md
|
74
59
|
- Rakefile
|
60
|
+
- TODO
|
75
61
|
- config.ru
|
62
|
+
- gem_version.rb
|
76
63
|
- knot.gemspec
|
77
64
|
- lib/knot.rb
|
78
65
|
- lib/knot/application.rb
|
@@ -117,6 +104,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
117
104
|
- - ! '>='
|
118
105
|
- !ruby/object:Gem::Version
|
119
106
|
version: '0'
|
107
|
+
segments:
|
108
|
+
- 0
|
109
|
+
hash: -2018670246009455394
|
120
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
111
|
none: false
|
122
112
|
requirements:
|
data/README
DELETED