expressr 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ module Expressr
2
+ class Route
3
+ def initialize(options={})
4
+ @router = options[:router] || raise('No router provided')
5
+ @path = options[:path] || raise('No path provided')
6
+ end
7
+
8
+ def all(&block)
9
+ @router.add_route(block, path: @path)
10
+ self
11
+ end
12
+
13
+ def get(&block)
14
+ @router.get(@path, &block)
15
+ self
16
+ end
17
+
18
+ def put(&block)
19
+ @router.put(@path, &block)
20
+ self
21
+ end
22
+
23
+ def post(&block)
24
+ @router.post(@path, &block)
25
+ self
26
+ end
27
+
28
+ def delete(&block)
29
+ @router.delete(@path, &block)
30
+ self
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,103 @@
1
+ module Expressr
2
+ class RouteItem
3
+ attr_reader :proc, :additional_arguments
4
+
5
+ def initialize(proc, options)
6
+ @proc = proc
7
+ @path = options[:path]
8
+ @method = options[:method]
9
+ @content_type = options[:content_type]
10
+ @param = options[:param] || []
11
+
12
+ @additional_arguments = []
13
+ set_path_token_and_param_names
14
+ end
15
+
16
+ def call(env, continue_method)
17
+ @env = env
18
+ @continue = continue_method
19
+ @env[:request].params.merge!(params)
20
+ @proc.call(@env[:request], @env[:response], @continue, *@additional_arguments)
21
+ continue
22
+ @env
23
+ end
24
+
25
+ def continue
26
+ @continue.call(@env)
27
+ end
28
+
29
+ def matches_env?(env)
30
+ matches_request?(env[:request])
31
+ end
32
+
33
+ def matches_request?(request)
34
+ content_type_matches?(request) &&
35
+ method_matches?(request.env) &&
36
+ path_matches?(request.env) &&
37
+ param_matches?(request)
38
+ end
39
+
40
+ def params
41
+ if @param_values.empty?
42
+ {}
43
+ else
44
+ if @param_names.empty?
45
+ @param_names = (0..(@param_values.length - 1)).to_a
46
+ end
47
+ Hash[@param_names.zip(@param_values)]
48
+ end
49
+ end
50
+
51
+ protected
52
+
53
+ def set_path_token_and_param_names
54
+ @path_token, @param_names = path_token_and_param_names(@path)
55
+ @param_values = []
56
+ end
57
+
58
+ def path_token_and_param_names(path)
59
+ if path.is_a?(String) && path =~ /:[a-z]/i
60
+ regexp = path.gsub(/:[a-z_]+/i, '([\w_]+)')
61
+ token = Regexp.new(regexp, Regexp::IGNORECASE)
62
+ param_names = path.scan(/:([a-z_]+)/i).flatten
63
+ [token, param_names]
64
+ else
65
+ [path, []]
66
+ end
67
+ end
68
+
69
+ def content_type_matches?(request)
70
+ return true if @content_type.nil?
71
+ !!request.accepts([@content_type])
72
+ end
73
+
74
+ def method_matches?(request_env)
75
+ return true if @method.nil?
76
+ @method == request_env[:request_method]
77
+ end
78
+
79
+ def path_matches?(request_env)
80
+ return true if @path.nil?
81
+
82
+ token = @path_token
83
+ request_uri = request_env[:request_uri]
84
+ if token.is_a?(String) && request_uri.end_with?(token)
85
+ return true
86
+ elsif token.is_a?(Regexp) && token =~ request_uri
87
+ @param_values = $~.to_a.drop(1)
88
+ return true
89
+ end
90
+ false
91
+ end
92
+
93
+ def param_matches?(request)
94
+ return true if @param.empty?
95
+ if request.params.keys.include?(@param)
96
+ @additional_arguments = [request.params[@param]]
97
+ true
98
+ else
99
+ false
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,22 @@
1
+ module Expressr
2
+ class RouteNode
3
+ def initialize(proc, next_node, options={})
4
+ @proc = proc
5
+ @next_node = next_node
6
+ @additional_arguments = options[:additional_arguments] || []
7
+ @has_continued = false
8
+ end
9
+
10
+ def call(request, response)
11
+ @request = request
12
+ @response = response
13
+ instance_exec(request, response, &@proc)
14
+ continue unless @has_continued
15
+ end
16
+
17
+ def continue
18
+ @has_continued = true
19
+ @next_node.call(@request, @response, *@additional_arguments)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+ module Expressr
2
+ class Router
3
+ attr_accessor :server
4
+
5
+ def initialize
6
+ @nodes = []
7
+ end
8
+
9
+ def use(path=nil, &block)
10
+ add_route(block, path: path)
11
+ end
12
+
13
+ def param(name, &block)
14
+ add_route(block, param: name)
15
+ end
16
+
17
+ def route(path)
18
+ Route.new(router: self, path: path)
19
+ end
20
+
21
+ def get(path, &block)
22
+ add_route(block, method: 'GET', path: path)
23
+ self
24
+ end
25
+
26
+ def put(path, &block)
27
+ add_route(block, method: 'PUT', path: path)
28
+ self
29
+ end
30
+
31
+ def post(path, &block)
32
+ add_route(block, method: 'POST', path: path)
33
+ self
34
+ end
35
+
36
+ def delete(path, &block)
37
+ add_route(block, method: 'DELETE', path: path)
38
+ self
39
+ end
40
+
41
+ def run(request, response)
42
+ env = {
43
+ request: request,
44
+ response: response
45
+ }
46
+ emit('request', env)
47
+ end
48
+
49
+ def add_route(proc, options={})
50
+ if options[:path]
51
+ options[:path] = standardize_path(options[:path])
52
+ end
53
+ callback = RouteItem.new(proc, options)
54
+ server.add_listener('request', callback)
55
+ end
56
+
57
+ protected
58
+
59
+ def standardize_path(path)
60
+ if path == '*'
61
+ path = nil
62
+ elsif path.is_a?(String) && path.include?('*')
63
+ path = Regexp.new("^#{path.gsub('*', '.*')}$")
64
+ end
65
+ path
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,46 @@
1
+ module Expressr
2
+ module Utils
3
+ # From ActiveSupport
4
+ def constantize(camel_cased_word)
5
+ names = camel_cased_word.split('::')
6
+
7
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
8
+ Object.const_get(camel_cased_word) if names.empty?
9
+
10
+ # Remove the first blank element in case of '::ClassName' notation.
11
+ names.shift if names.size > 1 && names.first.empty?
12
+
13
+ names.inject(Object) do |constant, name|
14
+ if constant == Object
15
+ constant.const_get(name)
16
+ else
17
+ candidate = constant.const_get(name)
18
+ next candidate if constant.const_defined?(name, false)
19
+ next candidate unless Object.const_defined?(name)
20
+
21
+ # Go down the ancestors to check it it's owned
22
+ # directly before we reach Object or the end of ancestors.
23
+ constant = constant.ancestors.inject do |const, ancestor|
24
+ break const if ancestor == Object
25
+ break ancestor if ancestor.const_defined?(name, false)
26
+ const
27
+ end
28
+
29
+ # owner is in Object, so raise
30
+ constant.const_get(name, false)
31
+ end
32
+ end
33
+ end
34
+ module_function :constantize
35
+
36
+ def standardize_content_type(content_type)
37
+ canonicalized_types = {
38
+ 'text' => 'text/plain',
39
+ 'html' => 'text/html',
40
+ 'json' => 'application/json'
41
+ }
42
+ canonicalized_types[content_type] || content_type
43
+ end
44
+ module_function :standardize_content_type
45
+ end
46
+ end
@@ -1,3 +1,3 @@
1
1
  module Expressr
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: expressr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-05-07 00:00:00.000000000 Z
12
+ date: 2014-05-13 00:00:00.000000000 Z
13
13
  dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: noder
16
+ requirement: !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: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: hashie
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mime-types
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'
14
62
  - !ruby/object:Gem::Dependency
15
63
  name: rspec
16
64
  requirement: !ruby/object:Gem::Requirement
@@ -27,6 +75,38 @@ dependencies:
27
75
  - - ! '>='
28
76
  - !ruby/object:Gem::Version
29
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: haml
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: slim
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
30
110
  description: Express.js for Ruby
31
111
  email:
32
112
  - tombenner@gmail.com
@@ -34,10 +114,25 @@ executables: []
34
114
  extensions: []
35
115
  extra_rdoc_files: []
36
116
  files:
117
+ - lib/expressr/app.rb
118
+ - lib/expressr/json.rb
119
+ - lib/expressr/listeners/request.rb
120
+ - lib/expressr/listeners/response.rb
121
+ - lib/expressr/renderer.rb
122
+ - lib/expressr/renderers/base.rb
123
+ - lib/expressr/renderers/haml.rb
124
+ - lib/expressr/renderers/slim.rb
125
+ - lib/expressr/renderers.rb
126
+ - lib/expressr/request.rb
127
+ - lib/expressr/response.rb
128
+ - lib/expressr/route.rb
129
+ - lib/expressr/route_item.rb
130
+ - lib/expressr/route_node.rb
131
+ - lib/expressr/router.rb
132
+ - lib/expressr/utils.rb
37
133
  - lib/expressr/version.rb
38
134
  - lib/expressr.rb
39
135
  - MIT-LICENSE
40
- - Rakefile
41
136
  - README.md
42
137
  homepage: https://github.com/tombenner/expressr
43
138
  licenses:
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
3
- require "rake/testtask"
4
-
5
- task :default => :test
6
-
7
- Rake::TestTask.new do |t|
8
- t.libs << "lib"
9
- t.libs << "test"
10
- t.test_files = FileList["test/**/*_test.rb"]
11
- t.verbose = true
12
- end