restfulness 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +342 -0
- data/Rakefile +1 -0
- data/example/Gemfile +5 -0
- data/example/README.md +42 -0
- data/example/app.rb +42 -0
- data/example/config.ru +5 -0
- data/lib/restfulness.rb +36 -0
- data/lib/restfulness/application.rb +83 -0
- data/lib/restfulness/dispatcher.rb +14 -0
- data/lib/restfulness/dispatchers/rack.rb +91 -0
- data/lib/restfulness/exceptions.rb +17 -0
- data/lib/restfulness/log_formatters/quiet_formatter.rb +7 -0
- data/lib/restfulness/log_formatters/verbose_formatter.rb +16 -0
- data/lib/restfulness/path.rb +46 -0
- data/lib/restfulness/request.rb +81 -0
- data/lib/restfulness/resource.rb +111 -0
- data/lib/restfulness/response.rb +57 -0
- data/lib/restfulness/route.rb +48 -0
- data/lib/restfulness/router.rb +27 -0
- data/lib/restfulness/statuses.rb +71 -0
- data/lib/restfulness/version.rb +3 -0
- data/restfulness.gemspec +29 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/unit/application_spec.rb +91 -0
- data/spec/unit/dispatcher_spec.rb +14 -0
- data/spec/unit/dispatchers/rack_spec.rb +34 -0
- data/spec/unit/exceptions_spec.rb +21 -0
- data/spec/unit/path_spec.rb +91 -0
- data/spec/unit/request_spec.rb +129 -0
- data/spec/unit/resource_spec.rb +245 -0
- data/spec/unit/response_spec.rb +65 -0
- data/spec/unit/route_spec.rb +160 -0
- data/spec/unit/router_spec.rb +103 -0
- metadata +189 -0
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Restfulness::Response do
|
5
|
+
|
6
|
+
class ResponseResource < Restfulness::Resource
|
7
|
+
end
|
8
|
+
|
9
|
+
let :klass do
|
10
|
+
Restfulness::Response
|
11
|
+
end
|
12
|
+
let :app do
|
13
|
+
Class.new(Restfulness::Application) do
|
14
|
+
routes do
|
15
|
+
add 'project', ResponseResource
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
let :request do
|
20
|
+
Restfulness::Request.new(app)
|
21
|
+
end
|
22
|
+
let :obj do
|
23
|
+
klass.new(request)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#initialize" do
|
27
|
+
it "should assign request and headers" do
|
28
|
+
obj.request.should eql(request)
|
29
|
+
obj.headers.should eql({'Content-Type' => 'application/json; charset=utf-8'})
|
30
|
+
obj.code.should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#run" do
|
35
|
+
context "without route" do
|
36
|
+
it "should not do anything" do
|
37
|
+
request.stub(:route).and_return(nil)
|
38
|
+
obj.run
|
39
|
+
obj.code.should eql(404)
|
40
|
+
obj.payload.should be_empty
|
41
|
+
obj.headers['Content-Length'].should eql(0.to_s)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
context "with route" do
|
45
|
+
let :route do
|
46
|
+
app.router.routes.first
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should try to build resource and run it" do
|
50
|
+
request.stub(:route).and_return(route)
|
51
|
+
request.action = :get
|
52
|
+
resource = double(:Resource)
|
53
|
+
resource.should_receive(:check_callbacks)
|
54
|
+
resource.should_receive(:call).and_return({:foo => 'bar'})
|
55
|
+
route.stub(:build_resource).and_return(resource)
|
56
|
+
obj.run
|
57
|
+
obj.code.should eql(200)
|
58
|
+
str = "{\"foo\":\"bar\"}"
|
59
|
+
obj.payload.should eql(str)
|
60
|
+
obj.headers['Content-Length'].should eql(str.bytesize.to_s)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Restfulness::Route do
|
5
|
+
|
6
|
+
class ATestResource < Restfulness::Resource
|
7
|
+
end
|
8
|
+
|
9
|
+
let :klass do
|
10
|
+
Restfulness::Route
|
11
|
+
end
|
12
|
+
|
13
|
+
let :resource do
|
14
|
+
ATestResource
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#initialize" do
|
18
|
+
|
19
|
+
it "should assign basic path and resource" do
|
20
|
+
obj = klass.new('project', resource)
|
21
|
+
obj.path.should eql(['project'])
|
22
|
+
obj.resource_name.should eql(resource.to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should assign path with symbols" do
|
26
|
+
obj = klass.new('project', :project_id, 'states', resource)
|
27
|
+
obj.path.should eql(['project', :project_id, 'states'])
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should remove :id from end" do
|
31
|
+
obj = klass.new('project', :project_id, 'states', :id, resource)
|
32
|
+
obj.path.should eql(['project', :project_id, 'states'])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should handle numbers in path" do
|
36
|
+
obj = klass.new('project', 120, resource)
|
37
|
+
obj.path.should eql(['project', 120])
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should accept classes as strings" do
|
41
|
+
expect {
|
42
|
+
obj = klass.new('project', resource.to_s)
|
43
|
+
}.to_not raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise name error if resource does not exist" do
|
47
|
+
expect {
|
48
|
+
klass.new('project')
|
49
|
+
}.to raise_error(NameError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should raise name error if no arguments" do
|
53
|
+
expect {
|
54
|
+
klass.new()
|
55
|
+
}.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#resource" do
|
61
|
+
it "should provide constant to class" do
|
62
|
+
obj = klass.new('project', resource)
|
63
|
+
obj.resource.should eql(resource)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "#build_path" do
|
68
|
+
it "should build a new path object including self" do
|
69
|
+
obj = klass.new('project', resource)
|
70
|
+
path = obj.build_path("/project/12345")
|
71
|
+
path.should be_a(Restfulness::Path)
|
72
|
+
path.route.should eql(obj)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#handles?" do
|
77
|
+
|
78
|
+
context "simple path" do
|
79
|
+
let :obj do
|
80
|
+
klass.new('project', resource)
|
81
|
+
end
|
82
|
+
it "should return true for match" do
|
83
|
+
obj.handles?(['project']).should be_true
|
84
|
+
end
|
85
|
+
it "should return true for match with id" do
|
86
|
+
obj.handles?(['project', '12345']).should be_true
|
87
|
+
end
|
88
|
+
it "should return false for different name" do
|
89
|
+
obj.handles?(['projects']).should be_false
|
90
|
+
end
|
91
|
+
it "should return false for matching start" do
|
92
|
+
obj.handles?(['project', '12345', 'status']).should be_false
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "catch all path" do
|
97
|
+
let :obj do
|
98
|
+
klass.new(resource)
|
99
|
+
end
|
100
|
+
it "should matching empty path" do
|
101
|
+
obj.handles?([]).should be_true
|
102
|
+
end
|
103
|
+
it "should matching empty path with id" do
|
104
|
+
obj.handles?(['12345']).should be_true
|
105
|
+
end
|
106
|
+
it "shold not match extended URL" do
|
107
|
+
obj.handles?(['foobar', '12345']).should be_false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "single variable path" do
|
112
|
+
let :obj do
|
113
|
+
klass.new(:project_id, resource)
|
114
|
+
end
|
115
|
+
it "should matching anything" do
|
116
|
+
obj.handles?(['foobar']).should be_true
|
117
|
+
end
|
118
|
+
it "should matching anything, with id" do
|
119
|
+
obj.handles?(['foobar', '12345']).should be_true
|
120
|
+
end
|
121
|
+
it "shold not match extended URL" do
|
122
|
+
obj.handles?(['foobar', 'status', '12345']).should be_false
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "complex path" do
|
127
|
+
let :obj do
|
128
|
+
klass.new('project', :project_id, 'status', resource)
|
129
|
+
end
|
130
|
+
it "should return true for match" do
|
131
|
+
obj.handles?(['project', '1234', 'status']).should be_true
|
132
|
+
end
|
133
|
+
it "should return true for match with id" do
|
134
|
+
obj.handles?(['project', '1234', 'status', '12345']).should be_true
|
135
|
+
end
|
136
|
+
it "should not match short path" do
|
137
|
+
obj.handles?(['project']).should be_false
|
138
|
+
end
|
139
|
+
it "should not match path with different name" do
|
140
|
+
obj.handles?(['project', '12345', 'statuses']).should be_false
|
141
|
+
end
|
142
|
+
it "should not match extended path" do
|
143
|
+
obj.handles?(['project', '12345', 'status', '1234', 'test']).should be_false
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#build_resource" do
|
151
|
+
|
152
|
+
it "should request a new resource" do
|
153
|
+
obj = klass.new('project', resource)
|
154
|
+
resource.should_receive(:new).with({}, {}).and_return(nil)
|
155
|
+
obj.build_resource({}, {})
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Restfulness::Router do
|
5
|
+
|
6
|
+
class RouterResource < Restfulness::Resource
|
7
|
+
end
|
8
|
+
|
9
|
+
let :klass do
|
10
|
+
Restfulness::Router
|
11
|
+
end
|
12
|
+
|
13
|
+
let :resource do
|
14
|
+
RouterResource
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#initialize" do
|
18
|
+
|
19
|
+
it "should prepare routes" do
|
20
|
+
obj = klass.new
|
21
|
+
obj.routes.should eql([])
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should prepare routes with instance eval block" do
|
25
|
+
block = lambda {}
|
26
|
+
obj = klass.new do
|
27
|
+
@foo = 'bar'
|
28
|
+
end
|
29
|
+
obj.instance_variable_get(:@foo).should eql('bar')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "#add" do
|
35
|
+
it "should add route to object" do
|
36
|
+
obj = klass.new
|
37
|
+
obj.add 'projects', resource
|
38
|
+
obj.routes.length.should eql(1)
|
39
|
+
route = obj.routes.first
|
40
|
+
route.should be_a(Restfulness::Route)
|
41
|
+
route.path.should eql(['projects'])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#route_for" do
|
46
|
+
let :obj do
|
47
|
+
res = resource
|
48
|
+
klass.new do
|
49
|
+
add 'projects', res
|
50
|
+
add 'project', :project_id, 'status', res
|
51
|
+
add :page, res
|
52
|
+
add res
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should determine the route for a simple path" do
|
57
|
+
route = obj.route_for("/projects")
|
58
|
+
route.should_not be_nil
|
59
|
+
route.path.should eql(['projects'])
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should determine the route for a simple path with id" do
|
63
|
+
route = obj.route_for("/projects")
|
64
|
+
route.should_not be_nil
|
65
|
+
route.path.should eql(['projects'])
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should determine the route for a simple path with id and end /" do
|
69
|
+
route = obj.route_for("/projects/12345/")
|
70
|
+
route.should_not be_nil
|
71
|
+
route.path.should eql(['projects'])
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should determine the route for a simple path with end /" do
|
75
|
+
route = obj.route_for("/projects/")
|
76
|
+
route.should_not be_nil
|
77
|
+
route.path.should eql(['projects'])
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should determine route for more complex path" do
|
81
|
+
route = obj.route_for("/project/1235/status/1234")
|
82
|
+
route.should_not be_nil
|
83
|
+
route.path.should eql(['project', :project_id, 'status'])
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should return nil if not matched" do
|
87
|
+
route = obj.route_for("/projects/1235/statuses/")
|
88
|
+
route.should be_nil
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should match empty path" do
|
92
|
+
route = obj.route_for("/")
|
93
|
+
route.path.should eql([])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should match path with single parameter" do
|
97
|
+
route = obj.route_for("/something")
|
98
|
+
route.path.should eql([:page])
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: restfulness
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Lown
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: multi_json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.8'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.8'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: activesupport
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mono_logger
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.3'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Simple REST server that focuses on resources instead of routes.
|
112
|
+
email:
|
113
|
+
- me@samlown.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- .gitignore
|
119
|
+
- Gemfile
|
120
|
+
- LICENSE.txt
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- example/Gemfile
|
124
|
+
- example/README.md
|
125
|
+
- example/app.rb
|
126
|
+
- example/config.ru
|
127
|
+
- lib/restfulness.rb
|
128
|
+
- lib/restfulness/application.rb
|
129
|
+
- lib/restfulness/dispatcher.rb
|
130
|
+
- lib/restfulness/dispatchers/rack.rb
|
131
|
+
- lib/restfulness/exceptions.rb
|
132
|
+
- lib/restfulness/log_formatters/quiet_formatter.rb
|
133
|
+
- lib/restfulness/log_formatters/verbose_formatter.rb
|
134
|
+
- lib/restfulness/path.rb
|
135
|
+
- lib/restfulness/request.rb
|
136
|
+
- lib/restfulness/resource.rb
|
137
|
+
- lib/restfulness/response.rb
|
138
|
+
- lib/restfulness/route.rb
|
139
|
+
- lib/restfulness/router.rb
|
140
|
+
- lib/restfulness/statuses.rb
|
141
|
+
- lib/restfulness/version.rb
|
142
|
+
- restfulness.gemspec
|
143
|
+
- spec/spec_helper.rb
|
144
|
+
- spec/unit/application_spec.rb
|
145
|
+
- spec/unit/dispatcher_spec.rb
|
146
|
+
- spec/unit/dispatchers/rack_spec.rb
|
147
|
+
- spec/unit/exceptions_spec.rb
|
148
|
+
- spec/unit/path_spec.rb
|
149
|
+
- spec/unit/request_spec.rb
|
150
|
+
- spec/unit/resource_spec.rb
|
151
|
+
- spec/unit/response_spec.rb
|
152
|
+
- spec/unit/route_spec.rb
|
153
|
+
- spec/unit/router_spec.rb
|
154
|
+
homepage: https://github.com/samlown/restfulness
|
155
|
+
licenses:
|
156
|
+
- MIT
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '>='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - '>='
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.0.3
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: Use to create a powerful, yet simple REST API in your application.
|
178
|
+
test_files:
|
179
|
+
- spec/spec_helper.rb
|
180
|
+
- spec/unit/application_spec.rb
|
181
|
+
- spec/unit/dispatcher_spec.rb
|
182
|
+
- spec/unit/dispatchers/rack_spec.rb
|
183
|
+
- spec/unit/exceptions_spec.rb
|
184
|
+
- spec/unit/path_spec.rb
|
185
|
+
- spec/unit/request_spec.rb
|
186
|
+
- spec/unit/resource_spec.rb
|
187
|
+
- spec/unit/response_spec.rb
|
188
|
+
- spec/unit/route_spec.rb
|
189
|
+
- spec/unit/router_spec.rb
|