knot 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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.8.0)
14
- rspec-core (~> 2.8.0)
15
- rspec-expectations (~> 2.8.0)
16
- rspec-mocks (~> 2.8.0)
17
- rspec-core (2.8.0)
18
- rspec-expectations (2.8.0)
19
- diff-lcs (~> 1.1.2)
20
- rspec-mocks (2.8.0)
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
@@ -0,0 +1,13 @@
1
+ - URL Helpers
2
+ - Test Helpers
3
+ - Error handlers -- 500 / 404
4
+ - Include layouts for erb
5
+
6
+ - Security:
7
+ - secure forms with authenticity token
8
+ - application auth token
9
+
10
+ - Assets
11
+ - investigate asset pipeline
12
+
13
+ - Travis build
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 'knot/version'
4
+ require './gem_version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "knot"
8
- gem.version = Knot::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
@@ -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(env)
36
- rescue => e
37
- return [500, {'Content-Type' => 'text/html'}, ["An error occured: ", e.message + "\n", e.backtrace.join("\n")]]
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(env)
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
- return [404, {"Content-Type" => "text/html"}, ["Aw snap"]]
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
@@ -16,7 +16,7 @@ module Knot::Dispatch
16
16
  private
17
17
 
18
18
  def http_method_match?(request)
19
- request.request_method == @http_method
19
+ request.request_method == @http_method
20
20
  end
21
21
  end
22
22
  end
@@ -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
- attr_reader :request, :response
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
- def initialize(request)
23
- @request = request
24
- @response = Knot::Dispatch::Response.new
24
+ return route
25
25
  end
26
26
 
27
- def _call!
28
- route = _config.routes.find { |route| route.match?(request) }
27
+ attr_reader :request, :response, :route
29
28
 
30
- raise Knot::Dispatch::NoRouteError, "no route matches #{request.path}" if route.nil?
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 = instance_eval &block
43
+ result = instance_exec error, &block
40
44
  response.body << result if result.is_a?(String)
41
45
  end.last
42
46
  }
@@ -1,6 +1,6 @@
1
1
  require 'knot/render'
2
2
  require 'knot/dispatch'
3
- require 'yajl/json_gem'
3
+ require 'json'
4
4
 
5
5
  module Knot::Dispatch
6
6
  class Router
@@ -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
@@ -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
 
@@ -27,5 +27,5 @@ describe Knot::Dispatch::Filter do
27
27
  filter.apply_to?(stub(:name => :another)).should be_true
28
28
  end
29
29
  end
30
- end
30
+ end
31
31
  end
@@ -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.1
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
@@ -1,2 +0,0 @@
1
- # Knot
2
- It's pretty much top secret.