acts_as_api 0.3.6 → 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +4 -0
- data/Rakefile +10 -9
- data/acts_as_api.gemspec +4 -5
- data/lib/acts_as_api/base.rb +16 -4
- data/lib/acts_as_api/responder.rb +10 -5
- data/lib/acts_as_api/version.rb +1 -1
- data/spec/controllers/respond_with_users_controller_spec.rb +92 -3
- data/spec/models/active_record_spec.rb +1 -0
- data/spec/models/mongoid_spec.rb +2 -1
- data/spec/models/vanilla_ruby_spec.rb +31 -0
- data/spec/rails_app/app/controllers/application_controller.rb +8 -0
- data/spec/rails_app/app/controllers/respond_with_users_controller.rb +15 -8
- data/spec/rails_app/app/controllers/users_controller.rb +13 -12
- data/spec/rails_app/app/models/mongo_user.rb +24 -0
- data/spec/rails_app/app/models/user.rb +73 -48
- data/spec/rails_app/app/models/vanilla_profile.rb +16 -0
- data/spec/rails_app/app/models/vanilla_task.rb +16 -0
- data/spec/rails_app/app/models/vanilla_untouched.rb +2 -0
- data/spec/rails_app/app/models/vanilla_user.rb +176 -0
- data/spec/rails_app/config/routes.rb +11 -3
- data/spec/support/controller_examples.rb +37 -2
- data/spec/support/model_examples/callbacks.rb +38 -0
- data/spec/support/simple_fixtures.rb +25 -1
- metadata +16 -4
data/History.txt
CHANGED
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'bundler'
|
2
2
|
require 'rspec/core'
|
3
3
|
require 'rspec/core/rake_task'
|
4
|
-
require 'rake/rdoctask'
|
4
|
+
#require 'rake/rdoctask'
|
5
5
|
|
6
6
|
Bundler::GemHelper.install_tasks
|
7
7
|
|
@@ -22,13 +22,14 @@ end
|
|
22
22
|
|
23
23
|
gemspec = Gem::Specification.load("acts_as_api.gemspec")
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
rdoc.
|
28
|
-
rdoc.
|
29
|
-
rdoc.options
|
30
|
-
rdoc.
|
31
|
-
rdoc.rdoc_files.include(
|
32
|
-
|
25
|
+
# causes crash in travis ci
|
26
|
+
#Rake::RDocTask.new do |rdoc|
|
27
|
+
# rdoc.rdoc_dir = 'doc'
|
28
|
+
# rdoc.title = "#{gemspec.name} #{gemspec.version}"
|
29
|
+
# rdoc.options += gemspec.rdoc_options
|
30
|
+
# rdoc.options << '--line-numbers' << '--inline-source'
|
31
|
+
# rdoc.rdoc_files.include(gemspec.extra_rdoc_files)
|
32
|
+
# rdoc.rdoc_files.include('README.rdoc')
|
33
|
+
#end
|
33
34
|
|
34
35
|
#bundle exec rocco examples/introduction/index.rb -t examples/introduction/layout.mustache
|
data/acts_as_api.gemspec
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# encoding: utf-8
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
require "acts_as_api/version"
|
4
4
|
|
@@ -15,11 +15,10 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.add_dependency('activemodel','>= 3.0.0')
|
16
16
|
s.add_dependency('activesupport','>= 3.0.0')
|
17
17
|
s.add_dependency('rack','>= 1.1.0')
|
18
|
-
|
18
|
+
|
19
19
|
s.add_development_dependency('rails', ['>= 3.0.0'])
|
20
20
|
s.add_development_dependency('mongoid', ['>= 2.0.0'])
|
21
|
-
|
22
|
-
s.has_rdoc = true
|
21
|
+
|
23
22
|
s.rdoc_options = ['--main', 'README.rdoc', '--charset=UTF-8']
|
24
23
|
s.extra_rdoc_files = ['README.rdoc']
|
25
24
|
|
@@ -27,4 +26,4 @@ Gem::Specification.new do |s|
|
|
27
26
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
27
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
29
28
|
s.require_paths = ["lib"]
|
30
|
-
end
|
29
|
+
end
|
data/lib/acts_as_api/base.rb
CHANGED
@@ -42,12 +42,13 @@ module ActsAsApi
|
|
42
42
|
yield attributes
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
class_attribute "api_accessible_#{api_template}".to_sym
|
46
|
+
send "api_accessible_#{api_template}=", attributes
|
46
47
|
end
|
47
48
|
|
48
49
|
# Returns an array of all the attributes that have been made accessible to the api response.
|
49
50
|
def api_accessible_attributes(api_template)
|
50
|
-
|
51
|
+
begin send "api_accessible_#{api_template}".to_sym rescue nil end
|
51
52
|
end
|
52
53
|
end
|
53
54
|
|
@@ -57,10 +58,21 @@ module ActsAsApi
|
|
57
58
|
# Will raise an exception if the passed api template is not defined for the model
|
58
59
|
def as_api_response(api_template)
|
59
60
|
api_attributes = self.class.api_accessible_attributes(api_template)
|
60
|
-
|
61
61
|
raise ActsAsApi::TemplateNotFoundError.new("acts_as_api template :#{api_template.to_s} was not found for model #{self.class}") if api_attributes.nil?
|
62
|
+
|
63
|
+
before_api_response(api_template) if respond_to? :before_api_response
|
62
64
|
|
63
|
-
|
65
|
+
response_hash = if respond_to? :around_api_response
|
66
|
+
around_api_response api_template do
|
67
|
+
api_attributes.to_response_hash(self)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
api_attributes.to_response_hash(self)
|
71
|
+
end
|
72
|
+
|
73
|
+
after_api_response(api_template) if respond_to? :after_api_response
|
74
|
+
|
75
|
+
response_hash
|
64
76
|
end
|
65
77
|
|
66
78
|
end
|
@@ -31,10 +31,15 @@ module ActsAsApi
|
|
31
31
|
super(controller, resources, options)
|
32
32
|
end
|
33
33
|
|
34
|
-
# Overrides the base implementation of
|
35
|
-
# the render_for_api method.
|
36
|
-
def
|
37
|
-
|
34
|
+
# Overrides the base implementation of display, replacing it with
|
35
|
+
# the render_for_api method whenever api_template is specified.
|
36
|
+
def display(resource, given_options={})
|
37
|
+
if api_template.nil? || !resource.respond_to?(:as_api_response)
|
38
|
+
controller.render given_options.merge!(options).merge!(format => resource)
|
39
|
+
else
|
40
|
+
controller.render_for_api api_template, given_options.merge!(options).merge!(format => resource)
|
41
|
+
end
|
38
42
|
end
|
43
|
+
|
39
44
|
end
|
40
|
-
end
|
45
|
+
end
|
data/lib/acts_as_api/version.rb
CHANGED
@@ -3,17 +3,18 @@ require 'spec_helper'
|
|
3
3
|
describe RespondWithUsersController do
|
4
4
|
|
5
5
|
context "using active record", :orm => :active_record do
|
6
|
-
|
6
|
+
|
7
7
|
before(:each) do
|
8
8
|
setup_active_record_models
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
after(:each) do
|
12
12
|
clean_up_active_record_models
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# see spec/support/controller_examples.rb
|
16
16
|
it_behaves_like "a controller with ActsAsApi responses"
|
17
|
+
|
17
18
|
end
|
18
19
|
|
19
20
|
context "using mongoid", :orm => :mongoid do
|
@@ -30,4 +31,92 @@ describe RespondWithUsersController do
|
|
30
31
|
it_behaves_like "a controller with ActsAsApi responses"
|
31
32
|
end
|
32
33
|
|
34
|
+
|
35
|
+
describe "default ActionController::Responder behavior" do
|
36
|
+
|
37
|
+
context 'json responses' do
|
38
|
+
|
39
|
+
context "creating valid models" do
|
40
|
+
|
41
|
+
before(:each) do
|
42
|
+
post :create, :user => { :first_name => "Luke", :last_name => "Skywalker" }, :api_template => :name_only, :format => 'json', :orm => :active_record
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return HTTP 201 status" do
|
46
|
+
response.code.should == "201"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should contain the specified attributes" do
|
50
|
+
response_body_json["user"].should have_key("first_name")
|
51
|
+
response_body_json["user"].should have_key("last_name")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should contain the specified values" do
|
55
|
+
response_body_json["user"]["first_name"].should eql("Luke")
|
56
|
+
response_body_json["user"]["last_name"].should eql("Skywalker")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "creating invalid models" do
|
61
|
+
|
62
|
+
before(:each) do
|
63
|
+
post :create, :user => {}, :api_template => :name_only, :format => 'json', :orm => :active_record
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return HTTP 422 status" do
|
67
|
+
response.code.should == "422"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should return errors as json" do
|
71
|
+
response_body_json['first_name'].should include("can't be blank")
|
72
|
+
response_body_json['last_name'].should include("can't be blank")
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'xml responses' do
|
80
|
+
|
81
|
+
context "creating valid models" do
|
82
|
+
|
83
|
+
before(:each) do
|
84
|
+
post :create, :user => { :first_name => "Luke", :last_name => "Skywalker" }, :api_template => :name_only, :format => 'xml', :orm => :active_record
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should return HTTP 201 status" do
|
88
|
+
response.code.should == "201"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should include HTTP Location header" do
|
92
|
+
response.headers["Location"].should == user_url(User.last)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should contain the specified attributes" do
|
96
|
+
response_body.should have_selector("user > first-name")
|
97
|
+
response_body.should have_selector("user > last-name")
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
context "creating invalid models" do
|
103
|
+
|
104
|
+
before(:each) do
|
105
|
+
post :create, :user => {}, :api_template => :name_only, :format => 'xml', :orm => :active_record
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should return HTTP 422 status" do
|
109
|
+
response.code.should == "422"
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should return errors as json" do
|
113
|
+
response_body.should have_selector("errors > error")
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
|
33
122
|
end
|
@@ -23,6 +23,7 @@ describe ActiveRecord, :orm => "active_record" do
|
|
23
23
|
it_supports "creating a sub hash in the api template"
|
24
24
|
it_supports "trying to render an api template that is not defined"
|
25
25
|
it_supports "untouched models"
|
26
|
+
it_supports "defining a model callback"
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
data/spec/models/mongoid_spec.rb
CHANGED
@@ -22,7 +22,8 @@ describe Mongoid, :orm => "mongoid" do
|
|
22
22
|
it_supports "listing attributes in the api template"
|
23
23
|
it_supports "creating a sub hash in the api template"
|
24
24
|
it_supports "trying to render an api template that is not defined"
|
25
|
-
it_supports "untouched models"
|
25
|
+
it_supports "untouched models"
|
26
|
+
it_supports "defining a model callback"
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Class, :orm => "vanilla" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
setup_roflscale_models
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
clean_up_roflscale_models
|
11
|
+
end
|
12
|
+
|
13
|
+
describe :act_as_api do
|
14
|
+
# deactivated as I won't implement a fake association model just for specs ;)
|
15
|
+
# it_supports "including an association in the api template"
|
16
|
+
it_supports "calling a closure in the api template"
|
17
|
+
it_supports "conditional if statements"
|
18
|
+
it_supports "conditional unless statements"
|
19
|
+
it_supports "acts_as_api is enabled"
|
20
|
+
it_supports "extending a given api template"
|
21
|
+
it_supports "calling a method in the api template"
|
22
|
+
it_supports "renaming"
|
23
|
+
it_supports "listing attributes in the api template"
|
24
|
+
it_supports "creating a sub hash in the api template"
|
25
|
+
it_supports "trying to render an api template that is not defined"
|
26
|
+
# deactivated as acts_as_api won't get mixed into any class
|
27
|
+
# it_supports "untouched models"
|
28
|
+
it_supports "defining a model callback"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -3,14 +3,6 @@ class RespondWithUsersController < ApplicationController
|
|
3
3
|
respond_to :json, :xml
|
4
4
|
|
5
5
|
self.responder = ActsAsApi::Responder
|
6
|
-
|
7
|
-
before_filter do
|
8
|
-
if params[:orm] == :active_record
|
9
|
-
@user_model = User
|
10
|
-
elsif params[:orm] == :mongoid
|
11
|
-
@user_model = MongoUser
|
12
|
-
end
|
13
|
-
end
|
14
6
|
|
15
7
|
def index
|
16
8
|
@users = @user_model.all
|
@@ -23,4 +15,19 @@ class RespondWithUsersController < ApplicationController
|
|
23
15
|
respond_with @user, :api_template => params[:api_template].to_sym, :root => :user
|
24
16
|
end
|
25
17
|
|
18
|
+
def show_default
|
19
|
+
@user = @user_model.find(params[:id])
|
20
|
+
respond_with @user
|
21
|
+
end
|
22
|
+
|
23
|
+
def create
|
24
|
+
@user = @user_model.new(params[:user])
|
25
|
+
|
26
|
+
if @user.save
|
27
|
+
respond_with @user, :api_template => params[:api_template]
|
28
|
+
else
|
29
|
+
respond_with @user
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
26
33
|
end
|
@@ -1,13 +1,5 @@
|
|
1
1
|
class UsersController < ApplicationController
|
2
|
-
|
3
|
-
before_filter do
|
4
|
-
if params[:orm] == :active_record
|
5
|
-
@user_model = User
|
6
|
-
elsif params[:orm] == :mongoid
|
7
|
-
@user_model = MongoUser
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
2
|
+
|
11
3
|
def index
|
12
4
|
@users = @user_model.all
|
13
5
|
|
@@ -16,7 +8,7 @@ class UsersController < ApplicationController
|
|
16
8
|
format.json { render_for_api params[:api_template].to_sym, :json => @users, :root => :users }
|
17
9
|
end
|
18
10
|
end
|
19
|
-
|
11
|
+
|
20
12
|
def show
|
21
13
|
@user = @user_model.find(params[:id])
|
22
14
|
|
@@ -25,6 +17,15 @@ class UsersController < ApplicationController
|
|
25
17
|
format.xml { render_for_api params[:api_template].to_sym, :xml => @user, :root => :user }
|
26
18
|
format.json { render_for_api params[:api_template].to_sym, :json => @user, :root => :user }
|
27
19
|
end
|
28
|
-
end
|
29
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def show_default
|
23
|
+
@user = @user_model.find(params[:id])
|
24
|
+
respond_to do |format|
|
25
|
+
format.xml { render :xml => @user }
|
26
|
+
format.json { render :json => @user }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
30
31
|
end
|
@@ -119,6 +119,30 @@ class MongoUser
|
|
119
119
|
t.add :last_name, :unless => lambda{|u| nil }
|
120
120
|
end
|
121
121
|
|
122
|
+
def before_api_response(api_response)
|
123
|
+
@before_api_response_called = true
|
124
|
+
end
|
125
|
+
|
126
|
+
def before_api_response_called?
|
127
|
+
!!@before_api_response_called
|
128
|
+
end
|
129
|
+
|
130
|
+
def after_api_response(api_response)
|
131
|
+
@after_api_response_called = true
|
132
|
+
end
|
133
|
+
|
134
|
+
def after_api_response_called?
|
135
|
+
!!@after_api_response_called
|
136
|
+
end
|
137
|
+
|
138
|
+
def skip_api_response=(should_skip)
|
139
|
+
@skip_api_response = should_skip
|
140
|
+
end
|
141
|
+
|
142
|
+
def around_api_response(api_response)
|
143
|
+
@skip_api_response ? { :skipped => true } : yield
|
144
|
+
end
|
145
|
+
|
122
146
|
def over_thirty?
|
123
147
|
age > 30
|
124
148
|
end
|
@@ -1,123 +1,148 @@
|
|
1
1
|
class User < ActiveRecord::Base
|
2
|
+
validates :first_name, :last_name, :presence => true
|
2
3
|
|
3
4
|
has_many :tasks
|
4
|
-
|
5
|
+
|
5
6
|
has_one :profile
|
6
|
-
|
7
|
+
|
7
8
|
acts_as_api
|
8
|
-
|
9
|
+
|
9
10
|
api_accessible :name_only do |t|
|
10
11
|
t.add :first_name
|
11
12
|
t.add :last_name
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
api_accessible :only_full_name do |t|
|
15
16
|
t.add :full_name
|
16
17
|
end
|
17
|
-
|
18
|
+
|
18
19
|
api_accessible :rename_last_name do |t|
|
19
20
|
t.add :last_name, :as => :family_name
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
api_accessible :rename_full_name do |t|
|
23
24
|
t.add :full_name, :as => :other_full_name
|
24
|
-
end
|
25
|
-
|
25
|
+
end
|
26
|
+
|
26
27
|
api_accessible :with_former_value do |t|
|
27
28
|
t.add :first_name
|
28
|
-
t.add :last_name
|
29
|
+
t.add :last_name
|
29
30
|
end
|
30
|
-
|
31
|
+
|
31
32
|
api_accessible :age_and_first_name, :extend => :with_former_value do |t|
|
32
33
|
t.add :age
|
33
34
|
t.remove :last_name
|
34
35
|
end
|
35
|
-
|
36
|
+
|
36
37
|
api_accessible :calling_a_proc do |t|
|
37
38
|
t.add Proc.new{|model| model.full_name.upcase }, :as => :all_caps_name
|
38
39
|
t.add Proc.new{|model| Time.now.class.to_s }, :as => :without_param
|
39
|
-
end
|
40
|
-
|
40
|
+
end
|
41
|
+
|
41
42
|
api_accessible :calling_a_lambda do |t|
|
42
43
|
t.add lambda{|model| model.full_name.upcase }, :as => :all_caps_name
|
43
44
|
t.add lambda{|model| Time.now.class.to_s }, :as => :without_param
|
44
45
|
end
|
45
|
-
api_accessible :include_tasks do |t|
|
46
|
+
api_accessible :include_tasks do |t|
|
46
47
|
t.add :tasks
|
47
48
|
end
|
48
|
-
|
49
|
-
api_accessible :include_profile do |t|
|
49
|
+
|
50
|
+
api_accessible :include_profile do |t|
|
50
51
|
t.add :profile
|
51
|
-
end
|
52
|
-
|
52
|
+
end
|
53
|
+
|
53
54
|
api_accessible :other_sub_template do |t|
|
54
55
|
t.add :first_name
|
55
56
|
t.add :tasks, :template => :other_template
|
56
57
|
end
|
57
|
-
|
58
|
-
api_accessible :include_completed_tasks do |t|
|
58
|
+
|
59
|
+
api_accessible :include_completed_tasks do |t|
|
59
60
|
t.add "tasks.completed.all", :as => :completed_tasks
|
60
61
|
end
|
61
|
-
|
62
|
-
api_accessible :sub_node do |t|
|
62
|
+
|
63
|
+
api_accessible :sub_node do |t|
|
63
64
|
t.add Hash[:foo => :say_something], :as => :sub_nodes
|
64
65
|
end
|
65
|
-
|
66
|
-
api_accessible :nested_sub_node do |t|
|
66
|
+
|
67
|
+
api_accessible :nested_sub_node do |t|
|
67
68
|
t.add Hash[:foo, Hash[:bar, :last_name]], :as => :sub_nodes
|
68
69
|
end
|
69
|
-
|
70
|
-
api_accessible :nested_sub_hash do |t|
|
70
|
+
|
71
|
+
api_accessible :nested_sub_hash do |t|
|
71
72
|
t.add :sub_hash
|
72
73
|
end
|
73
|
-
|
74
|
-
api_accessible :if_over_thirty do |t|
|
74
|
+
|
75
|
+
api_accessible :if_over_thirty do |t|
|
75
76
|
t.add :first_name
|
76
|
-
t.add :last_name, :if => :over_thirty?
|
77
|
-
end
|
77
|
+
t.add :last_name, :if => :over_thirty?
|
78
|
+
end
|
78
79
|
|
79
|
-
api_accessible :if_returns_nil do |t|
|
80
|
+
api_accessible :if_returns_nil do |t|
|
80
81
|
t.add :first_name
|
81
82
|
t.add :last_name, :if => :return_nil
|
82
83
|
end
|
83
|
-
|
84
|
-
api_accessible :if_over_thirty_proc do |t|
|
84
|
+
|
85
|
+
api_accessible :if_over_thirty_proc do |t|
|
85
86
|
t.add :first_name
|
86
87
|
t.add :last_name, :if => lambda{|u| u.over_thirty? }
|
87
|
-
end
|
88
|
+
end
|
88
89
|
|
89
|
-
api_accessible :if_returns_nil_proc do |t|
|
90
|
+
api_accessible :if_returns_nil_proc do |t|
|
90
91
|
t.add :first_name
|
91
92
|
t.add :last_name, :if => lambda{|u| nil }
|
92
93
|
end
|
93
|
-
|
94
|
-
api_accessible :unless_under_thirty do |t|
|
94
|
+
|
95
|
+
api_accessible :unless_under_thirty do |t|
|
95
96
|
t.add :first_name
|
96
|
-
t.add :last_name, :unless => :under_thirty?
|
97
|
-
end
|
97
|
+
t.add :last_name, :unless => :under_thirty?
|
98
|
+
end
|
98
99
|
|
99
|
-
api_accessible :unless_returns_nil do |t|
|
100
|
+
api_accessible :unless_returns_nil do |t|
|
100
101
|
t.add :first_name
|
101
102
|
t.add :last_name, :unless => :return_nil
|
102
103
|
end
|
103
|
-
|
104
|
-
api_accessible :unless_under_thirty_proc do |t|
|
104
|
+
|
105
|
+
api_accessible :unless_under_thirty_proc do |t|
|
105
106
|
t.add :first_name
|
106
107
|
t.add :last_name, :unless => lambda{|u| u.under_thirty? }
|
107
|
-
end
|
108
|
+
end
|
108
109
|
|
109
|
-
api_accessible :unless_returns_nil_proc do |t|
|
110
|
+
api_accessible :unless_returns_nil_proc do |t|
|
110
111
|
t.add :first_name
|
111
112
|
t.add :last_name, :unless => lambda{|u| nil }
|
112
|
-
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def before_api_response(api_response)
|
116
|
+
@before_api_response_called = true
|
117
|
+
end
|
118
|
+
|
119
|
+
def before_api_response_called?
|
120
|
+
!!@before_api_response_called
|
121
|
+
end
|
122
|
+
|
123
|
+
def after_api_response(api_response)
|
124
|
+
@after_api_response_called = true
|
125
|
+
end
|
126
|
+
|
127
|
+
def after_api_response_called?
|
128
|
+
!!@after_api_response_called
|
129
|
+
end
|
130
|
+
|
131
|
+
def skip_api_response=(should_skip)
|
132
|
+
@skip_api_response = should_skip
|
133
|
+
end
|
134
|
+
|
135
|
+
def around_api_response(api_response)
|
136
|
+
@skip_api_response ? { :skipped => true } : yield
|
137
|
+
end
|
113
138
|
|
114
139
|
def over_thirty?
|
115
140
|
age > 30
|
116
141
|
end
|
117
|
-
|
142
|
+
|
118
143
|
def under_thirty?
|
119
144
|
age < 30
|
120
|
-
end
|
145
|
+
end
|
121
146
|
|
122
147
|
def return_nil
|
123
148
|
nil
|
@@ -130,7 +155,7 @@ class User < ActiveRecord::Base
|
|
130
155
|
def say_something
|
131
156
|
"something"
|
132
157
|
end
|
133
|
-
|
158
|
+
|
134
159
|
def sub_hash
|
135
160
|
{
|
136
161
|
:foo => "bar",
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class VanillaProfile
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :user, :avatar, :homepage, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
opts.each do |k,v|
|
8
|
+
self.send :"#{k}=", v
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def model_name
|
13
|
+
'profile'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class VanillaTask
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :user, :heading, :description, :time_spent, :done, :created_at, :updated_at
|
5
|
+
|
6
|
+
def initialize(opts)
|
7
|
+
opts.each do |k,v|
|
8
|
+
self.send :"#{k}=", v
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def model_name
|
13
|
+
'task'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
class VanillaUser
|
2
|
+
extend ActsAsApi::Base
|
3
|
+
|
4
|
+
attr_accessor :profile, :tasks, :first_name, :last_name, :age, :active, :created_at, :updated_at
|
5
|
+
|
6
|
+
|
7
|
+
def initialize(opts)
|
8
|
+
@tasks = []
|
9
|
+
opts.each do |k,v|
|
10
|
+
self.send :"#{k}=", v
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def model_name
|
15
|
+
'user'
|
16
|
+
end
|
17
|
+
|
18
|
+
acts_as_api
|
19
|
+
|
20
|
+
api_accessible :name_only do |t|
|
21
|
+
t.add :first_name
|
22
|
+
t.add :last_name
|
23
|
+
end
|
24
|
+
|
25
|
+
api_accessible :only_full_name do |t|
|
26
|
+
t.add :full_name
|
27
|
+
end
|
28
|
+
|
29
|
+
api_accessible :rename_last_name do |t|
|
30
|
+
t.add :last_name, :as => :family_name
|
31
|
+
end
|
32
|
+
|
33
|
+
api_accessible :rename_full_name do |t|
|
34
|
+
t.add :full_name, :as => :other_full_name
|
35
|
+
end
|
36
|
+
|
37
|
+
api_accessible :with_former_value do |t|
|
38
|
+
t.add :first_name
|
39
|
+
t.add :last_name
|
40
|
+
end
|
41
|
+
|
42
|
+
api_accessible :age_and_first_name, :extend => :with_former_value do |t|
|
43
|
+
t.add :age
|
44
|
+
t.remove :last_name
|
45
|
+
end
|
46
|
+
|
47
|
+
api_accessible :calling_a_proc do |t|
|
48
|
+
t.add Proc.new{|model| model.full_name.upcase }, :as => :all_caps_name
|
49
|
+
t.add Proc.new{|model| Time.now.class.to_s }, :as => :without_param
|
50
|
+
end
|
51
|
+
|
52
|
+
api_accessible :calling_a_lambda do |t|
|
53
|
+
t.add lambda{|model| model.full_name.upcase }, :as => :all_caps_name
|
54
|
+
t.add lambda{|model| Time.now.class.to_s }, :as => :without_param
|
55
|
+
end
|
56
|
+
api_accessible :include_tasks do |t|
|
57
|
+
t.add :tasks
|
58
|
+
end
|
59
|
+
|
60
|
+
api_accessible :include_profile do |t|
|
61
|
+
t.add :profile
|
62
|
+
end
|
63
|
+
|
64
|
+
api_accessible :other_sub_template do |t|
|
65
|
+
t.add :first_name
|
66
|
+
t.add :tasks, :template => :other_template
|
67
|
+
end
|
68
|
+
|
69
|
+
api_accessible :include_completed_tasks do |t|
|
70
|
+
t.add "tasks.completed.all", :as => :completed_tasks
|
71
|
+
end
|
72
|
+
|
73
|
+
api_accessible :sub_node do |t|
|
74
|
+
t.add Hash[:foo => :say_something], :as => :sub_nodes
|
75
|
+
end
|
76
|
+
|
77
|
+
api_accessible :nested_sub_node do |t|
|
78
|
+
t.add Hash[:foo, Hash[:bar, :last_name]], :as => :sub_nodes
|
79
|
+
end
|
80
|
+
|
81
|
+
api_accessible :nested_sub_hash do |t|
|
82
|
+
t.add :sub_hash
|
83
|
+
end
|
84
|
+
|
85
|
+
api_accessible :if_over_thirty do |t|
|
86
|
+
t.add :first_name
|
87
|
+
t.add :last_name, :if => :over_thirty?
|
88
|
+
end
|
89
|
+
|
90
|
+
api_accessible :if_returns_nil do |t|
|
91
|
+
t.add :first_name
|
92
|
+
t.add :last_name, :if => :return_nil
|
93
|
+
end
|
94
|
+
|
95
|
+
api_accessible :if_over_thirty_proc do |t|
|
96
|
+
t.add :first_name
|
97
|
+
t.add :last_name, :if => lambda{|u| u.over_thirty? }
|
98
|
+
end
|
99
|
+
|
100
|
+
api_accessible :if_returns_nil_proc do |t|
|
101
|
+
t.add :first_name
|
102
|
+
t.add :last_name, :if => lambda{|u| nil }
|
103
|
+
end
|
104
|
+
|
105
|
+
api_accessible :unless_under_thirty do |t|
|
106
|
+
t.add :first_name
|
107
|
+
t.add :last_name, :unless => :under_thirty?
|
108
|
+
end
|
109
|
+
|
110
|
+
api_accessible :unless_returns_nil do |t|
|
111
|
+
t.add :first_name
|
112
|
+
t.add :last_name, :unless => :return_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
api_accessible :unless_under_thirty_proc do |t|
|
116
|
+
t.add :first_name
|
117
|
+
t.add :last_name, :unless => lambda{|u| u.under_thirty? }
|
118
|
+
end
|
119
|
+
|
120
|
+
api_accessible :unless_returns_nil_proc do |t|
|
121
|
+
t.add :first_name
|
122
|
+
t.add :last_name, :unless => lambda{|u| nil }
|
123
|
+
end
|
124
|
+
|
125
|
+
def before_api_response(api_response)
|
126
|
+
@before_api_response_called = true
|
127
|
+
end
|
128
|
+
|
129
|
+
def before_api_response_called?
|
130
|
+
!!@before_api_response_called
|
131
|
+
end
|
132
|
+
|
133
|
+
def after_api_response(api_response)
|
134
|
+
@after_api_response_called = true
|
135
|
+
end
|
136
|
+
|
137
|
+
def after_api_response_called?
|
138
|
+
!!@after_api_response_called
|
139
|
+
end
|
140
|
+
|
141
|
+
def skip_api_response=(should_skip)
|
142
|
+
@skip_api_response = should_skip
|
143
|
+
end
|
144
|
+
|
145
|
+
def around_api_response(api_response)
|
146
|
+
@skip_api_response ? { :skipped => true } : yield
|
147
|
+
end
|
148
|
+
|
149
|
+
def over_thirty?
|
150
|
+
age > 30
|
151
|
+
end
|
152
|
+
|
153
|
+
def under_thirty?
|
154
|
+
age < 30
|
155
|
+
end
|
156
|
+
|
157
|
+
def return_nil
|
158
|
+
nil
|
159
|
+
end
|
160
|
+
|
161
|
+
def full_name
|
162
|
+
'' << first_name.to_s << ' ' << last_name.to_s
|
163
|
+
end
|
164
|
+
|
165
|
+
def say_something
|
166
|
+
"something"
|
167
|
+
end
|
168
|
+
|
169
|
+
def sub_hash
|
170
|
+
{
|
171
|
+
:foo => "bar",
|
172
|
+
:hello => "world"
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
@@ -1,7 +1,15 @@
|
|
1
1
|
RailsApp::Application.routes.draw do
|
2
2
|
|
3
|
-
resources :users
|
4
|
-
|
5
|
-
|
3
|
+
resources :users do
|
4
|
+
member do
|
5
|
+
get 'show_default'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
resources :respond_with_users do
|
10
|
+
member do
|
11
|
+
get 'show_default'
|
12
|
+
end
|
13
|
+
end
|
6
14
|
|
7
15
|
end
|
@@ -44,8 +44,28 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
44
44
|
|
45
45
|
end
|
46
46
|
|
47
|
-
|
47
|
+
describe 'get a user without specifying an api template' do
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
get :show_default, :format => 'xml', :id => @luke.id, :orm => @orm_for_testing
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should respond with HTTP 200" do
|
54
|
+
response.code.should == "200"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should render the model with standard to_xml" do
|
58
|
+
# TODO: figure out how to compare xml generated by mongo models.
|
59
|
+
|
60
|
+
# This line works fine with ActiveRecord, but not Mongoid:
|
61
|
+
# response.body.should == @luke.to_xml
|
62
|
+
|
63
|
+
response.body.length.should == @luke.to_xml.length
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
48
67
|
|
68
|
+
end
|
49
69
|
|
50
70
|
describe 'json responses' do
|
51
71
|
|
@@ -124,6 +144,22 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
124
144
|
|
125
145
|
end
|
126
146
|
|
147
|
+
describe 'get a user without specifying an api template' do
|
148
|
+
|
149
|
+
before(:each) do
|
150
|
+
get :show_default, :format => 'json', :id => @luke.id, :orm => @orm_for_testing
|
151
|
+
end
|
152
|
+
|
153
|
+
it "should respond with HTTP 200" do
|
154
|
+
response.code.should == "200"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should render the model with to_json" do
|
158
|
+
response.body.should == @luke.to_json
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
127
163
|
end
|
128
164
|
|
129
165
|
describe 'Rails 3 default style json responses' do
|
@@ -242,5 +278,4 @@ shared_examples_for "a controller with ActsAsApi responses" do
|
|
242
278
|
end
|
243
279
|
end
|
244
280
|
|
245
|
-
|
246
281
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
shared_examples_for "defining a model callback" do
|
2
|
+
|
3
|
+
describe "for a" do
|
4
|
+
|
5
|
+
describe "around_api_response" do
|
6
|
+
|
7
|
+
it "skips rendering if not yielded" do
|
8
|
+
@luke.skip_api_response = true
|
9
|
+
@luke.as_api_response(:name_only).keys.should include(:skipped)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "renders if yielded" do
|
13
|
+
@luke.as_api_response(:name_only).keys.should_not include(:skipped)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "before_api_response" do
|
19
|
+
|
20
|
+
it "is called properly" do
|
21
|
+
@luke.as_api_response(:name_only)
|
22
|
+
@luke.before_api_response_called?.should eql(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "after_api_response" do
|
28
|
+
|
29
|
+
it "is called properly" do
|
30
|
+
@luke.as_api_response(:name_only)
|
31
|
+
@luke.after_api_response_called?.should eql(true)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -21,7 +21,7 @@ module SimpleFixtures
|
|
21
21
|
def clean_up_active_record_models
|
22
22
|
@user_model.delete_all
|
23
23
|
@task_model.delete_all
|
24
|
-
end
|
24
|
+
end
|
25
25
|
|
26
26
|
def setup_mongoid_models
|
27
27
|
@orm_for_testing = :mongoid
|
@@ -49,6 +49,30 @@ module SimpleFixtures
|
|
49
49
|
@user_model.delete_all
|
50
50
|
end
|
51
51
|
|
52
|
+
def setup_roflscale_models
|
53
|
+
@orm_for_testing = :vanilla
|
54
|
+
@user_model = VanillaUser
|
55
|
+
@task_model = VanillaTask
|
56
|
+
@profile_model = VanillaProfile
|
57
|
+
@untouched_model = VanillaUntouched
|
58
|
+
|
59
|
+
@luke = @user_model.new({ :first_name => 'Luke', :last_name => 'Skywalker', :age => 25, :active => true })
|
60
|
+
@han = @user_model.new({ :first_name => 'Han', :last_name => 'Solo', :age => 35, :active => true })
|
61
|
+
@leia = @user_model.new({ :first_name => 'Princess', :last_name => 'Leia', :age => 25, :active => false })
|
62
|
+
|
63
|
+
@luke.profile = @profile_model.new({ :user => @luke, :avatar => 'picard.jpg', :homepage => 'lukasarts.com' })
|
64
|
+
|
65
|
+
@destroy_deathstar = @task_model.new({ :user => @luke, :heading => "Destroy Deathstar", :description => "XWing, Shoot, BlowUp", :time_spent => 30, :done => true })
|
66
|
+
@study_with_yoda = @task_model.new({ :user => @luke, :heading => "Study with Yoda", :description => "Jedi Stuff, ya know", :time_spent => 60, :done => true })
|
67
|
+
@win_rebellion = @task_model.new({ :user => @luke, :heading => "Win Rebellion", :description => "no idea yet...", :time_spent => 180, :done => false })
|
68
|
+
|
69
|
+
@luke.tasks << @destroy_deathstar << @study_with_yoda << @win_rebellion
|
70
|
+
end
|
71
|
+
|
72
|
+
def clean_up_roflscale_models
|
73
|
+
# nothing to do ;)
|
74
|
+
end
|
75
|
+
|
52
76
|
end
|
53
77
|
|
54
78
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 7
|
10
|
+
version: 0.3.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Christian B\xC3\xA4uerlein"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-06-13 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -134,6 +134,7 @@ files:
|
|
134
134
|
- spec/controllers/users_controller_spec.rb
|
135
135
|
- spec/models/active_record_spec.rb
|
136
136
|
- spec/models/mongoid_spec.rb
|
137
|
+
- spec/models/vanilla_ruby_spec.rb
|
137
138
|
- spec/rails_app/.gitignore
|
138
139
|
- spec/rails_app/Rakefile
|
139
140
|
- spec/rails_app/app/controllers/application_controller.rb
|
@@ -148,6 +149,10 @@ files:
|
|
148
149
|
- spec/rails_app/app/models/task.rb
|
149
150
|
- spec/rails_app/app/models/untouched.rb
|
150
151
|
- spec/rails_app/app/models/user.rb
|
152
|
+
- spec/rails_app/app/models/vanilla_profile.rb
|
153
|
+
- spec/rails_app/app/models/vanilla_task.rb
|
154
|
+
- spec/rails_app/app/models/vanilla_untouched.rb
|
155
|
+
- spec/rails_app/app/models/vanilla_user.rb
|
151
156
|
- spec/rails_app/app/views/layouts/application.html.erb
|
152
157
|
- spec/rails_app/config.ru
|
153
158
|
- spec/rails_app/config/application.rb
|
@@ -191,6 +196,7 @@ files:
|
|
191
196
|
- spec/support/controller_examples.rb
|
192
197
|
- spec/support/it_supports.rb
|
193
198
|
- spec/support/model_examples/associations.rb
|
199
|
+
- spec/support/model_examples/callbacks.rb
|
194
200
|
- spec/support/model_examples/closures.rb
|
195
201
|
- spec/support/model_examples/conditional_if.rb
|
196
202
|
- spec/support/model_examples/conditional_unless.rb
|
@@ -244,6 +250,7 @@ test_files:
|
|
244
250
|
- spec/controllers/users_controller_spec.rb
|
245
251
|
- spec/models/active_record_spec.rb
|
246
252
|
- spec/models/mongoid_spec.rb
|
253
|
+
- spec/models/vanilla_ruby_spec.rb
|
247
254
|
- spec/rails_app/.gitignore
|
248
255
|
- spec/rails_app/Rakefile
|
249
256
|
- spec/rails_app/app/controllers/application_controller.rb
|
@@ -258,6 +265,10 @@ test_files:
|
|
258
265
|
- spec/rails_app/app/models/task.rb
|
259
266
|
- spec/rails_app/app/models/untouched.rb
|
260
267
|
- spec/rails_app/app/models/user.rb
|
268
|
+
- spec/rails_app/app/models/vanilla_profile.rb
|
269
|
+
- spec/rails_app/app/models/vanilla_task.rb
|
270
|
+
- spec/rails_app/app/models/vanilla_untouched.rb
|
271
|
+
- spec/rails_app/app/models/vanilla_user.rb
|
261
272
|
- spec/rails_app/app/views/layouts/application.html.erb
|
262
273
|
- spec/rails_app/config.ru
|
263
274
|
- spec/rails_app/config/application.rb
|
@@ -301,6 +312,7 @@ test_files:
|
|
301
312
|
- spec/support/controller_examples.rb
|
302
313
|
- spec/support/it_supports.rb
|
303
314
|
- spec/support/model_examples/associations.rb
|
315
|
+
- spec/support/model_examples/callbacks.rb
|
304
316
|
- spec/support/model_examples/closures.rb
|
305
317
|
- spec/support/model_examples/conditional_if.rb
|
306
318
|
- spec/support/model_examples/conditional_unless.rb
|