ananke 0.1.0 → 0.1.1
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/Gemfile +2 -2
- data/README.rdoc +6 -6
- data/lib/ananke/helpers.rb +42 -0
- data/lib/ananke/routing.rb +19 -23
- data/lib/ananke/validation.rb +1 -1
- data/lib/ananke.rb +1 -1
- data/lib/version.rb +1 -1
- data/spec/lib/ananke_spec.rb +16 -14
- data/spec/lib/json_spec.rb +51 -0
- data/spec/lib/link_to_spec.rb +1 -1
- data/spec/lib/linked_spec.rb +4 -4
- data/spec/lib/route_for_spec.rb +2 -2
- data/spec/lib/validation_spec.rb +3 -3
- metadata +19 -17
data/Gemfile
CHANGED
@@ -4,12 +4,12 @@ gem "colored", "~>1.2"
|
|
4
4
|
gem "json", "~>1.5.1"
|
5
5
|
gem "sinatra", "~>1.1.2"
|
6
6
|
|
7
|
-
group :development, :test do
|
7
|
+
#group :development, :test do
|
8
8
|
gem "rack-test", "~>0.5.6"
|
9
9
|
gem "rake", "~>0.8.7"
|
10
10
|
gem "rspec", "~>2.5.0"
|
11
11
|
gem 'simplecov', '~>0.4.0'
|
12
|
-
end
|
12
|
+
#end
|
13
13
|
|
14
14
|
|
15
15
|
|
data/README.rdoc
CHANGED
@@ -19,7 +19,7 @@ Ananke is a DSL that extends the functionality of Sinatra for easy creation of R
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
#-------------------REST Resources--------------------
|
22
|
-
|
22
|
+
route :user do
|
23
23
|
id :id
|
24
24
|
end
|
25
25
|
|
@@ -34,7 +34,7 @@ One User
|
|
34
34
|
http://localhost:4567/user/1
|
35
35
|
|
36
36
|
== REST Resources
|
37
|
-
`
|
37
|
+
`route` defines a complete Resource, and constructs Sinatra Routes
|
38
38
|
based on what's available in it's respective Repository. Routes are:
|
39
39
|
|
40
40
|
get '/name/?' -> Repository::Capitalize(name).all
|
@@ -51,7 +51,7 @@ The Default Repository can be changed:
|
|
51
51
|
== HyperMedia
|
52
52
|
=== Linked
|
53
53
|
|
54
|
-
|
54
|
+
route :user do
|
55
55
|
id :id
|
56
56
|
linked :computer
|
57
57
|
end
|
@@ -99,11 +99,11 @@ The link to <b>Self</b> uses this method. The output will be something like this
|
|
99
99
|
|
100
100
|
=== Link To and Route For
|
101
101
|
|
102
|
-
|
102
|
+
route :user do
|
103
103
|
id :id
|
104
104
|
link_to :car
|
105
105
|
end
|
106
|
-
|
106
|
+
route :car do
|
107
107
|
id :id
|
108
108
|
route_for :user
|
109
109
|
end
|
@@ -148,7 +148,7 @@ Output:
|
|
148
148
|
This way of linking solves a lot of problems, and can also be used for searching support.
|
149
149
|
<b>route_for</b> supports an optional 2nd parameter to specify the type of request it must register for:
|
150
150
|
|
151
|
-
|
151
|
+
route :car do
|
152
152
|
id :id
|
153
153
|
route_for :user, :post
|
154
154
|
end
|
data/lib/ananke/helpers.rb
CHANGED
@@ -40,4 +40,46 @@ module Ananke
|
|
40
40
|
puts message unless message.nil?
|
41
41
|
message
|
42
42
|
end
|
43
|
+
|
44
|
+
def symbolize_keys(hash)
|
45
|
+
new_hash = {}
|
46
|
+
hash.each{|k,v| new_hash[k.to_sym] = Hash === v ? symbolize_keys(v) : v}
|
47
|
+
new_hash
|
48
|
+
end
|
49
|
+
|
50
|
+
def collect_params(params)
|
51
|
+
new_params = {}
|
52
|
+
params.each do |k,v|
|
53
|
+
json = symbolize_keys(JSON.parse(k)) if v.nil?
|
54
|
+
if !json.nil? && !json.empty?
|
55
|
+
new_params.merge!(json)
|
56
|
+
else
|
57
|
+
new_params[k.to_sym] = v
|
58
|
+
end
|
59
|
+
end
|
60
|
+
new_params
|
61
|
+
end
|
62
|
+
|
63
|
+
def define_repository_call(mod, method_name)
|
64
|
+
inputs = mod.method(method_name).parameters
|
65
|
+
repository_name = mod.name.split('::').last
|
66
|
+
call_def = "def self.call_#{repository_name}_#{method_name}(params)"
|
67
|
+
case inputs.length
|
68
|
+
when 0
|
69
|
+
call_def << "#{mod}.send(:#{method_name})"
|
70
|
+
when 1
|
71
|
+
call_def << "#{mod}.send(:#{method_name}, params[:key])"
|
72
|
+
else
|
73
|
+
input_array = []
|
74
|
+
inputs.each{|i| input_array << "params[:#{i[1]}]"}
|
75
|
+
call_def << "#{mod}.send(:#{method_name}, #{input_array.join(',')})"
|
76
|
+
end
|
77
|
+
call_def << "end"
|
78
|
+
Ananke.send(:eval, call_def)
|
79
|
+
end
|
80
|
+
|
81
|
+
def repository_call(mod, method_name, params)
|
82
|
+
repository_name = mod.name.split('::').last
|
83
|
+
Ananke.send("call_#{repository_name}_#{method_name}", params)
|
84
|
+
end
|
43
85
|
end
|
data/lib/ananke/routing.rb
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
require './lib/ananke/validation'
|
2
|
+
require './lib/ananke/linking'
|
3
|
+
require './lib/ananke/helpers'
|
4
|
+
|
1
5
|
module Ananke
|
2
6
|
public
|
3
7
|
class << self
|
@@ -14,6 +18,7 @@ module Ananke
|
|
14
18
|
|
15
19
|
def build_route(mod, mod_method, verb, route, &block)
|
16
20
|
if mod.respond_to? mod_method
|
21
|
+
define_repository_call(mod, mod_method)
|
17
22
|
add_route(route.split('/')[1], mod_method)
|
18
23
|
Sinatra::Base.send verb, "#{route}", do
|
19
24
|
instance_eval(&block)
|
@@ -74,11 +79,13 @@ module Ananke
|
|
74
79
|
|
75
80
|
#===========================POST===============================
|
76
81
|
build_route mod, :add, :post, "/#{path}/?" do
|
77
|
-
|
82
|
+
new_params = collect_params(params)
|
83
|
+
status, message = validate(fields, new_params)
|
78
84
|
error status, message unless status.nil?
|
79
|
-
|
85
|
+
|
86
|
+
obj = repository_call(mod, :add, new_params)
|
80
87
|
|
81
|
-
links = build_links(link_list, link_to_list, path,
|
88
|
+
links = build_links(link_list, link_to_list, path, new_params[key], mod)
|
82
89
|
json = get_json(path, obj, links)
|
83
90
|
|
84
91
|
status 201
|
@@ -87,10 +94,12 @@ module Ananke
|
|
87
94
|
|
88
95
|
#===========================PUT================================
|
89
96
|
build_route mod, :edit, :put, "/#{path}/:#{key}" do
|
90
|
-
|
91
|
-
|
97
|
+
new_params = collect_params(params)
|
98
|
+
param_missing!(key) if new_params[key].nil?
|
99
|
+
status, message = validate(fields, new_params)
|
92
100
|
error status, message unless status.nil?
|
93
|
-
|
101
|
+
|
102
|
+
obj = repository_call(mod, :edit, new_params)
|
94
103
|
|
95
104
|
links = build_links(link_list, link_to_list, path, params[key], mod)
|
96
105
|
json = get_json(path, obj, links)
|
@@ -120,24 +129,11 @@ module Ananke
|
|
120
129
|
full_path = "/#{path}/#{r[:name]}"
|
121
130
|
full_path << "/:key" if inputs.length == 1
|
122
131
|
|
123
|
-
call_def = "def self.call_#{path}_#{r[:name]}(params)"
|
124
|
-
case inputs.length
|
125
|
-
when 0
|
126
|
-
call_def << "#{mod}.send(:#{r[:name]})"
|
127
|
-
when 1
|
128
|
-
call_def << "#{mod}.send(:#{r[:name]}, params[:key])"
|
129
|
-
else
|
130
|
-
input_array = []
|
131
|
-
inputs.each{|i| input_array << "params[:#{i[1]}]"}
|
132
|
-
call_def << "#{mod}.send(:#{r[:name]}, #{input_array.join(',')})"
|
133
|
-
end
|
134
|
-
call_def << "end"
|
135
|
-
puts call_def
|
136
|
-
Ananke.send(:eval, call_def)
|
137
|
-
|
138
132
|
build_route mod, r[:name], r[:verb], full_path do
|
139
|
-
|
140
|
-
|
133
|
+
new_params = collect_params(params)
|
134
|
+
param_missing!(:key) if inputs.length == 1 && new_params[:key].nil?
|
135
|
+
|
136
|
+
obj = repository_call(mod, r[:name], new_params)
|
141
137
|
|
142
138
|
links = build_links(link_list, link_to_list, "#{path}/#{r[:name]}", params[:key], mod)
|
143
139
|
json = get_json("#{path}/#{r[:name]}", obj, links)
|
data/lib/ananke/validation.rb
CHANGED
@@ -10,7 +10,7 @@ module Ananke
|
|
10
10
|
def validate(fields, params)
|
11
11
|
errors = []
|
12
12
|
fields.each do |field|
|
13
|
-
value = params[field[:key]
|
13
|
+
value = params[field[:key]]
|
14
14
|
errors << "Missing Required Parameter: #{field[:key]}" if field[:type] == :required && value.nil?
|
15
15
|
Ananke::Rules.value = value
|
16
16
|
field[:rules].each do |r|
|
data/lib/ananke.rb
CHANGED
data/lib/version.rb
CHANGED
data/spec/lib/ananke_spec.rb
CHANGED
@@ -21,7 +21,7 @@ describe 'Basic Ananke REST' do
|
|
21
21
|
it """
|
22
22
|
Should be able to describe a Valid REST Resource
|
23
23
|
""" do
|
24
|
-
|
24
|
+
route :user do
|
25
25
|
id :user_id
|
26
26
|
end
|
27
27
|
end
|
@@ -29,7 +29,7 @@ describe 'Basic Ananke REST' do
|
|
29
29
|
it """
|
30
30
|
Should skip creating Routes for Non-Existing Repositories
|
31
31
|
""" do
|
32
|
-
|
32
|
+
route :invalid do
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -104,7 +104,7 @@ describe 'Basic Ananke REST' do
|
|
104
104
|
- content-type: text/json
|
105
105
|
- body:
|
106
106
|
""" do
|
107
|
-
put "/user/3", body={:
|
107
|
+
put "/user/3", body={:username => 'four'}
|
108
108
|
check_status(200)
|
109
109
|
end
|
110
110
|
|
@@ -128,7 +128,7 @@ describe 'Basic Ananke REST' do
|
|
128
128
|
- content-type: text/json
|
129
129
|
- body: Missing Parameter: user_id
|
130
130
|
""" do
|
131
|
-
put "/user", body={:
|
131
|
+
put "/user", body={:username => 'four'}
|
132
132
|
check_status(400)
|
133
133
|
last_response.body.should == 'Missing Parameter: user_id'
|
134
134
|
end
|
@@ -155,22 +155,24 @@ module Repository
|
|
155
155
|
@data
|
156
156
|
end
|
157
157
|
|
158
|
-
def self.one(
|
159
|
-
@data[@data.index{ |d| d[:user_id] ==
|
158
|
+
def self.one(user_id)
|
159
|
+
@data[@data.index{ |d| d[:user_id] == user_id.to_i}]
|
160
160
|
end
|
161
161
|
def self.all
|
162
162
|
@data
|
163
163
|
end
|
164
|
-
def self.add(
|
165
|
-
|
166
|
-
data
|
164
|
+
def self.add(user_id, username)
|
165
|
+
obj = {:user_id => user_id.to_i, :username => username}
|
166
|
+
@data << obj
|
167
|
+
obj
|
167
168
|
end
|
168
|
-
def self.edit(
|
169
|
-
|
170
|
-
data
|
169
|
+
def self.edit(user_id, username)
|
170
|
+
obj = {:user_id => user_id.to_i, :username => username}
|
171
|
+
@data[@data.index{|i| i[:user_id] == user_id.to_i}] = obj
|
172
|
+
obj
|
171
173
|
end
|
172
|
-
def self.delete(
|
173
|
-
@data.delete_if { |i| i[:user_id] ==
|
174
|
+
def self.delete(user_id)
|
175
|
+
@data.delete_if { |i| i[:user_id] == user_id.to_i}
|
174
176
|
end
|
175
177
|
end
|
176
178
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require './spec/spec_helper'
|
2
|
+
|
3
|
+
describe 'Ananke - JSON Body' do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
include Ananke
|
6
|
+
|
7
|
+
def app
|
8
|
+
Sinatra::Base
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be able to parse a JSON Body in a basic POST route" do
|
12
|
+
post "/json", body={:name => 'one', :surname => 'sur_one'}.to_json
|
13
|
+
check_status(201)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be able to parse a JSON Body in a basic PUT route" do
|
17
|
+
put "/json/1", body={:name => 'one', :surname => 'sur_one'}.to_json
|
18
|
+
check_status(200)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be able to parse a JSON Body in a Custom Route" do
|
22
|
+
get "/json/custom", body={:name => 'one', :surname => 'sur_one'}.to_json
|
23
|
+
check_status(200)
|
24
|
+
end
|
25
|
+
|
26
|
+
module Repository
|
27
|
+
module Json
|
28
|
+
@data = []
|
29
|
+
def self.add(name, surname)
|
30
|
+
id = @data.empty? && 1 || @data.last[:id] + 1
|
31
|
+
obj = {:id => id, :name => name, :surname => surname}
|
32
|
+
@data << obj
|
33
|
+
obj
|
34
|
+
end
|
35
|
+
def self.edit(id, name, surname)
|
36
|
+
obj = {:id => id, :name => name, :surname => surname}
|
37
|
+
@data[@data.index{|i| i[:id] == id.to_i}] = obj
|
38
|
+
obj
|
39
|
+
end
|
40
|
+
def self.custom(name, surname)
|
41
|
+
@data[@data.index{|i| i[:name] == name && i[:surname] == surname}]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
route :json do
|
46
|
+
id :id
|
47
|
+
required :name
|
48
|
+
required :surname
|
49
|
+
route_for :custom
|
50
|
+
end
|
51
|
+
end
|
data/spec/lib/link_to_spec.rb
CHANGED
data/spec/lib/linked_spec.rb
CHANGED
@@ -20,7 +20,7 @@ describe 'Resource' do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
route :self do
|
24
24
|
id :user_id
|
25
25
|
end
|
26
26
|
|
@@ -56,11 +56,11 @@ describe 'Resource' do
|
|
56
56
|
def self.one(id) end
|
57
57
|
end
|
58
58
|
end
|
59
|
-
|
59
|
+
route :linked do
|
60
60
|
id :user_id
|
61
61
|
linked :line
|
62
62
|
end
|
63
|
-
|
63
|
+
route :line do
|
64
64
|
id :line_id
|
65
65
|
end
|
66
66
|
|
@@ -95,7 +95,7 @@ describe 'Resource' do
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
98
|
-
|
98
|
+
route :linked_fail do
|
99
99
|
id :user_id
|
100
100
|
linked :line
|
101
101
|
end
|
data/spec/lib/route_for_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe 'Resource Route-For' do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
route :route_for do
|
23
23
|
id :link_id
|
24
24
|
route_for :custom
|
25
25
|
end
|
@@ -39,7 +39,7 @@ describe 'Resource Route-For' do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
42
|
+
route :route_for do
|
43
43
|
id :link_id
|
44
44
|
route_for :multi, :post
|
45
45
|
end
|
data/spec/lib/validation_spec.rb
CHANGED
@@ -19,7 +19,7 @@ describe 'Resource' do
|
|
19
19
|
def self.add(data)end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
route :basic do
|
23
23
|
id :user_id
|
24
24
|
required :username, :length => 4
|
25
25
|
end
|
@@ -49,7 +49,7 @@ describe 'Resource' do
|
|
49
49
|
def self.add(data)end
|
50
50
|
end
|
51
51
|
end
|
52
|
-
|
52
|
+
route :explicit do
|
53
53
|
id :user_id
|
54
54
|
required :email, :email
|
55
55
|
end
|
@@ -73,7 +73,7 @@ describe 'Resource' do
|
|
73
73
|
def self.add(data)end
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
route :added do
|
77
77
|
id :user_id
|
78
78
|
required :country, :country
|
79
79
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ananke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.1.
|
5
|
+
version: 0.1.1
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Andries Coetzee
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-02-
|
13
|
+
date: 2011-02-18 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -100,23 +100,24 @@ extra_rdoc_files:
|
|
100
100
|
- README.rdoc
|
101
101
|
files:
|
102
102
|
- lib/ananke.rb
|
103
|
+
- lib/version.rb
|
103
104
|
- lib/ananke/settings.rb
|
104
|
-
- lib/ananke/helpers.rb
|
105
105
|
- lib/ananke/linking.rb
|
106
|
-
- lib/ananke/validation.rb
|
107
106
|
- lib/ananke/routing.rb
|
108
|
-
- lib/
|
109
|
-
-
|
110
|
-
- spec/call_chain.rb
|
107
|
+
- lib/ananke/validation.rb
|
108
|
+
- lib/ananke/helpers.rb
|
111
109
|
- spec/dumping.rb
|
112
110
|
- spec/cov_adapter.rb
|
113
111
|
- spec/lib/ananke_spec.rb
|
114
|
-
- spec/lib/route_for_spec.rb
|
115
|
-
- spec/lib/out_spec.rb
|
116
112
|
- spec/lib/validation_spec.rb
|
117
|
-
- spec/lib/
|
113
|
+
- spec/lib/out_spec.rb
|
114
|
+
- spec/lib/json_spec.rb
|
118
115
|
- spec/lib/link_to_spec.rb
|
116
|
+
- spec/lib/route_for_spec.rb
|
117
|
+
- spec/lib/linked_spec.rb
|
119
118
|
- spec/spec_helper.rb
|
119
|
+
- spec/call_chain.rb
|
120
|
+
- spec/nice_formatter.rb
|
120
121
|
- Gemfile
|
121
122
|
- Rakefile
|
122
123
|
- README.rdoc
|
@@ -127,7 +128,7 @@ licenses: []
|
|
127
128
|
post_install_message: |
|
128
129
|
**************************************************
|
129
130
|
|
130
|
-
Thank you for installing ananke-0.1.
|
131
|
+
Thank you for installing ananke-0.1.1
|
131
132
|
|
132
133
|
Please be sure to look at README.rdoc to see what might have changed
|
133
134
|
since the last release and how to use this GEM.
|
@@ -156,16 +157,17 @@ rubyforge_project:
|
|
156
157
|
rubygems_version: 1.5.0
|
157
158
|
signing_key:
|
158
159
|
specification_version: 3
|
159
|
-
summary: ananke-0.1.
|
160
|
+
summary: ananke-0.1.1
|
160
161
|
test_files:
|
161
|
-
- spec/nice_formatter.rb
|
162
|
-
- spec/call_chain.rb
|
163
162
|
- spec/dumping.rb
|
164
163
|
- spec/cov_adapter.rb
|
165
164
|
- spec/lib/ananke_spec.rb
|
166
|
-
- spec/lib/route_for_spec.rb
|
167
|
-
- spec/lib/out_spec.rb
|
168
165
|
- spec/lib/validation_spec.rb
|
169
|
-
- spec/lib/
|
166
|
+
- spec/lib/out_spec.rb
|
167
|
+
- spec/lib/json_spec.rb
|
170
168
|
- spec/lib/link_to_spec.rb
|
169
|
+
- spec/lib/route_for_spec.rb
|
170
|
+
- spec/lib/linked_spec.rb
|
171
171
|
- spec/spec_helper.rb
|
172
|
+
- spec/call_chain.rb
|
173
|
+
- spec/nice_formatter.rb
|