ananke 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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
- rest :user do
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
- `rest` defines a complete Resource, and constructs Sinatra Routes
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
- rest :user do
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
- rest :user do
102
+ route :user do
103
103
  id :id
104
104
  link_to :car
105
105
  end
106
- rest :car do
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
- rest :car do
151
+ route :car do
152
152
  id :id
153
153
  route_for :user, :post
154
154
  end
@@ -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
@@ -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
- status, message = validate(fields, params)
82
+ new_params = collect_params(params)
83
+ status, message = validate(fields, new_params)
78
84
  error status, message unless status.nil?
79
- obj = mod.add(params)
85
+
86
+ obj = repository_call(mod, :add, new_params)
80
87
 
81
- links = build_links(link_list, link_to_list, path, params[key], mod)
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
- param_missing!(key) if params[key].nil?
91
- status, message = validate(fields, params)
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
- obj = mod.edit(params[key], params)
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
- param_missing!(:key) if inputs.length == 1 && params[:key].nil?
140
- obj = Ananke.send("call_#{path}_#{r[:name]}", params)
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)
@@ -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].to_s]
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
@@ -16,7 +16,7 @@ module Ananke
16
16
 
17
17
  public
18
18
  #===========================DSL================================
19
- def rest(path, &block)
19
+ def route(path, &block)
20
20
  @id = {}
21
21
  @fields = []
22
22
  @link_list = []
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ananke
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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
- rest :user do
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
- rest :invalid do
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={:user_id => 3, :username => 'four'}
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={:user_id => 3, :username => 'four'}
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(id)
159
- @data[@data.index{ |d| d[:user_id] == id.to_i}]
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(data)
165
- @data << data
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(id, data)
169
- @data.each { |d| d = data if d[:user_id] == id}
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(id)
173
- @data.delete_if { |i| i[:user_id] == 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
@@ -19,7 +19,7 @@ describe 'Link-To Resource' do
19
19
  end
20
20
  end
21
21
  end
22
- rest :link_to do
22
+ route :link_to do
23
23
  id :link_id
24
24
  link_to :to
25
25
  end
@@ -20,7 +20,7 @@ describe 'Resource' do
20
20
  end
21
21
  end
22
22
  end
23
- rest :self do
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
- rest :linked do
59
+ route :linked do
60
60
  id :user_id
61
61
  linked :line
62
62
  end
63
- rest :line do
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
- rest :linked_fail do
98
+ route :linked_fail do
99
99
  id :user_id
100
100
  linked :line
101
101
  end
@@ -19,7 +19,7 @@ describe 'Resource Route-For' do
19
19
  end
20
20
  end
21
21
  end
22
- rest :route_for do
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
- rest :route_for do
42
+ route :route_for do
43
43
  id :link_id
44
44
  route_for :multi, :post
45
45
  end
@@ -19,7 +19,7 @@ describe 'Resource' do
19
19
  def self.add(data)end
20
20
  end
21
21
  end
22
- rest :basic do
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
- rest :explicit do
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
- rest :added do
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.0
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-15 00:00:00 +02:00
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/version.rb
109
- - spec/nice_formatter.rb
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/linked_spec.rb
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.0
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.0
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/linked_spec.rb
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