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.
@@ -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