amfetamine 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.md +196 -0
- data/Rakefile +11 -0
- data/amfetamine.gemspec +40 -0
- data/lib/amfetamine.rb +19 -0
- data/lib/amfetamine/base.rb +189 -0
- data/lib/amfetamine/cache.rb +9 -0
- data/lib/amfetamine/caching_adapter.rb +66 -0
- data/lib/amfetamine/config.rb +34 -0
- data/lib/amfetamine/exceptions.rb +9 -0
- data/lib/amfetamine/helpers/rspec_matchers.rb +5 -0
- data/lib/amfetamine/helpers/test_helpers.rb +113 -0
- data/lib/amfetamine/logger.rb +18 -0
- data/lib/amfetamine/query_methods.rb +187 -0
- data/lib/amfetamine/relationship.rb +108 -0
- data/lib/amfetamine/relationships.rb +77 -0
- data/lib/amfetamine/rest_helpers.rb +122 -0
- data/lib/amfetamine/version.rb +3 -0
- data/spec/amfetamine/base_spec.rb +207 -0
- data/spec/amfetamine/caching_spec.rb +37 -0
- data/spec/amfetamine/callbacks_spec.rb +36 -0
- data/spec/amfetamine/conditions_spec.rb +110 -0
- data/spec/amfetamine/dummy_spec.rb +27 -0
- data/spec/amfetamine/relationships_spec.rb +103 -0
- data/spec/amfetamine/rest_helpers_spec.rb +25 -0
- data/spec/amfetamine/rspec_matchers_spec.rb +7 -0
- data/spec/amfetamine/testing_helpers_spec.rb +101 -0
- data/spec/dummy/child.rb +25 -0
- data/spec/dummy/configure.rb +4 -0
- data/spec/dummy/dummy.rb +48 -0
- data/spec/dummy/dummy_rest_client.rb +6 -0
- data/spec/helpers/active_model_lint.rb +21 -0
- data/spec/helpers/fakeweb_responses.rb +120 -0
- data/spec/spec_helper.rb +33 -0
- metadata +246 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Amfetamine::Cache do
|
4
|
+
it "should return same data after all request has been made" do
|
5
|
+
dummy = build(:dummy)
|
6
|
+
dummy2 = build(:dummy)
|
7
|
+
dummies = nil
|
8
|
+
stub_all_response(dummy, dummy2) do
|
9
|
+
dummies = Dummy.all
|
10
|
+
end
|
11
|
+
dummies_no_request = Dummy.all
|
12
|
+
dummies.should == dummies
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return same data after find request has been made" do
|
16
|
+
dummy = build(:dummy)
|
17
|
+
return_dummy = nil
|
18
|
+
stub_single_response(dummy) do
|
19
|
+
return_dummy = Dummy.find(dummy.id)
|
20
|
+
end
|
21
|
+
dummy_no_request = Dummy.find(dummy.id)
|
22
|
+
dummy_no_request.should == return_dummy
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should update the cache after a save has been made" do
|
26
|
+
dummy = build(:dummy)
|
27
|
+
dummy.instance_variable_set('@notsaved', false)
|
28
|
+
dummy.title = 'blabla'
|
29
|
+
stub_update_response(dummy) do
|
30
|
+
dummy.save
|
31
|
+
end
|
32
|
+
dummy2 = Dummy.find(dummy.id)
|
33
|
+
dummy2.should == dummy
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe "Callbacks" do
|
5
|
+
before do
|
6
|
+
Dummy.stub_responses! do |r|
|
7
|
+
r.post { build(:dummy) }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "create" do
|
12
|
+
it "should work with before" do
|
13
|
+
Dummy.any_instance.should_receive(:"action_before_create")
|
14
|
+
Dummy.create
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should work with after" do
|
18
|
+
pending "Not working, but not needed either"
|
19
|
+
Dummy.any_instance.should_receive(:"action_after_create")
|
20
|
+
Dummy.create
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "save" do
|
25
|
+
it "should work" do
|
26
|
+
dummy = build(:dummy)
|
27
|
+
dummy.should_receive(:"action_before_save")
|
28
|
+
dummy.should_receive(:"action_after_save")
|
29
|
+
dummy.save
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Amfetamine REST Helpers with conditions" do
|
4
|
+
it "should work regular #all" do
|
5
|
+
Dummy.cache.flush # Just to be uber sure
|
6
|
+
|
7
|
+
query = {:title => 'Dummy'}
|
8
|
+
dummy = build(:dummy)
|
9
|
+
dummy.instance_variable_set('@notsaved',false)
|
10
|
+
|
11
|
+
result = nil
|
12
|
+
stub_conditional_all_response(query, dummy) do
|
13
|
+
result = Dummy.all(:conditions => query)
|
14
|
+
end
|
15
|
+
result2 = Dummy.all(:conditions => query) # No errors raised means it got it from the cache
|
16
|
+
result.should == result2
|
17
|
+
result.should include(dummy)
|
18
|
+
Dummy.prevent_external_connections! do |resource|
|
19
|
+
resource.delete {}
|
20
|
+
dummy.destroy
|
21
|
+
end
|
22
|
+
|
23
|
+
lambda {Dummy.all(:conditions => query) }.should raise_exception(FakeWeb::NetConnectNotAllowedError)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should work with nested resource #all" do
|
27
|
+
Dummy.cache.flush # Just to be uber sure
|
28
|
+
Child.cache.flush
|
29
|
+
|
30
|
+
query = {:title => 'Child'}
|
31
|
+
dummy = build(:dummy)
|
32
|
+
child = build(:child)
|
33
|
+
dummy.children << child
|
34
|
+
|
35
|
+
dummy.instance_variable_set('@notsaved',false)
|
36
|
+
child.instance_variable_set('@notsaved',false)
|
37
|
+
|
38
|
+
result = nil
|
39
|
+
stub_conditional_nested_all_response(dummy, query, child) do
|
40
|
+
result = dummy.children.all(:conditions => query)
|
41
|
+
end
|
42
|
+
result2 = dummy.children.all(:conditions => query) # No errors raised means it got it from the cache
|
43
|
+
result.should == result2
|
44
|
+
result.should include(child)
|
45
|
+
|
46
|
+
|
47
|
+
stub_delete_response(child) do
|
48
|
+
child.destroy
|
49
|
+
end
|
50
|
+
|
51
|
+
child.should_not be_cached
|
52
|
+
|
53
|
+
lambda {dummy.children.all(:conditions => query, :force => true) }.should raise_exception(FakeWeb::NetConnectNotAllowedError)
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should work with normal resource #find" do
|
57
|
+
dummy = build(:dummy)
|
58
|
+
query = { :title => 'Dummy' }
|
59
|
+
|
60
|
+
Dummy.stub_responses! do |r|
|
61
|
+
r.get(:path => "/dummies/#{dummy.id}", :code => 200) { dummy }
|
62
|
+
r.get(:path => "/dummies/#{dummy.id}", :code => 200, :query => query) { dummy }
|
63
|
+
r.delete(:path => "/dummies/#{dummy.id}", :code => 200) {}
|
64
|
+
end
|
65
|
+
|
66
|
+
Dummy.cache.flush
|
67
|
+
|
68
|
+
dummy.instance_variable_set('@notsaved',false)
|
69
|
+
|
70
|
+
result = Dummy.find(dummy.id)
|
71
|
+
result.should == dummy
|
72
|
+
|
73
|
+
result2 = Dummy.find(dummy.id, :conditions => query)
|
74
|
+
result2.should == result
|
75
|
+
|
76
|
+
dummy.destroy
|
77
|
+
|
78
|
+
dummy.should_not be_cached
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
it "should work with nested resource #find" do
|
83
|
+
Dummy.cache.flush
|
84
|
+
Child.cache.flush
|
85
|
+
|
86
|
+
query = { :title => 'Dummy' }
|
87
|
+
dummy = build(:dummy)
|
88
|
+
child = build(:child)
|
89
|
+
dummy.children << child
|
90
|
+
|
91
|
+
dummy.instance_variable_set('@notsaved',false)
|
92
|
+
child.instance_variable_set('@notsaved',false)
|
93
|
+
|
94
|
+
result = nil
|
95
|
+
stub_conditional_nested_single_response(dummy,child, query) do
|
96
|
+
result = dummy.children.find(dummy.id, :conditions => query)
|
97
|
+
end
|
98
|
+
|
99
|
+
result.should == child
|
100
|
+
|
101
|
+
result2 = dummy.children.find(dummy.id, :conditions => query)
|
102
|
+
result2.should == result
|
103
|
+
|
104
|
+
stub_delete_response(child) do
|
105
|
+
child.destroy
|
106
|
+
end
|
107
|
+
|
108
|
+
child.should_not be_cached
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dummy do
|
4
|
+
context "ActiveModel Lint test" do
|
5
|
+
subject { Dummy.new }
|
6
|
+
it_should_behave_like "ActiveModel"
|
7
|
+
end
|
8
|
+
|
9
|
+
context "Client side validation" do
|
10
|
+
let(:dummy) { Dummy.new }
|
11
|
+
|
12
|
+
it "should not be valid" do
|
13
|
+
dummy.should_not be_valid
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "Configuration" do
|
18
|
+
it "should be configurable" do
|
19
|
+
Dummy.amfetamine_configure :memcached_instance => ['localhost:11211', {:key => 1}], :rest_client => DummyRestClient, :resource_suffix => '.json'
|
20
|
+
cs = Dummy.instance_variable_get('@cache_server')
|
21
|
+
cs.should be_a(Amfetamine::Cache)
|
22
|
+
cs.instance_variable_get('@cache_server').instance_variable_get('@options').should include(:key => 1) # Annoying bug :/
|
23
|
+
Dummy.rest_client.should == DummyRestClient
|
24
|
+
Dummy.resource_suffix.should == '.json'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Amfetamine::Relationships do
|
4
|
+
let(:dummy) {build :dummy}
|
5
|
+
let(:child) {build :child}
|
6
|
+
|
7
|
+
context "Routing" do
|
8
|
+
it "should generate correct paths" do
|
9
|
+
dummy.children << child
|
10
|
+
|
11
|
+
Child.rest_path.should == "/children"
|
12
|
+
child.rest_path.should == "/children"
|
13
|
+
child.singular_path.should == "/children/#{child.id}"
|
14
|
+
dummy.children.rest_path.should == "/dummies/#{dummy.id}/children"
|
15
|
+
|
16
|
+
Child.resource_suffix = '.json'
|
17
|
+
child.rest_path.should == "/children.json"
|
18
|
+
dummy.children.rest_path.should == "/dummies/#{dummy.id}/children.json"
|
19
|
+
child.singular_path.should == "/children/#{child.id}.json"
|
20
|
+
|
21
|
+
Child.resource_suffix = ''
|
22
|
+
child.dummy.singular_path.should == "/dummies/#{dummy.id}/children/#{child.id}"
|
23
|
+
dummy.children.find_path(child.id).should == "/dummies/#{dummy.id}/children/#{child.id}"
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should raise error if nested path lacks parent id" do
|
27
|
+
child = Child.new({:title => 'test', :dummy_id => nil})
|
28
|
+
|
29
|
+
lambda { child.belongs_to_relationships.first.rest_path }.should raise_exception(Amfetamine::InvalidPath)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "Adding and modifying children" do
|
34
|
+
before(:each) do
|
35
|
+
dummy.children << child
|
36
|
+
child.instance_variable_set(:@notsaved, false)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should create a relationship if parent id is passed in params" do
|
40
|
+
child2 = Child.new(:title => 'Child2', :dummy_id => dummy.id)
|
41
|
+
child2.dummy.should be_a(Amfetamine::Relationship)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should be possible list all children" do
|
45
|
+
dummy.children.should include(child)
|
46
|
+
Dummy.cache.flush
|
47
|
+
dummy.children.should include(child)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be possible to get all children if not in memory" do
|
51
|
+
Dummy.cache.flush
|
52
|
+
new_dummy = nil
|
53
|
+
stub_single_response(dummy) do
|
54
|
+
new_dummy = Dummy.find(dummy.id)
|
55
|
+
end
|
56
|
+
|
57
|
+
children = nil
|
58
|
+
stub_nested_all_response(dummy,child) do
|
59
|
+
children = new_dummy.children.all
|
60
|
+
end
|
61
|
+
children.should include(child)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be possible to get a single child if not in memory" do
|
65
|
+
child.attributes[:dummy_id] = dummy.id # Lets fake we saved it.
|
66
|
+
Dummy.cache.flush
|
67
|
+
new_dummy = nil
|
68
|
+
stub_single_response(dummy) do
|
69
|
+
new_dummy = Dummy.find(dummy.id)
|
70
|
+
end
|
71
|
+
|
72
|
+
new_child = nil
|
73
|
+
stub_nested_single_response(dummy,child) do
|
74
|
+
new_child = new_dummy.children.find(child.id)
|
75
|
+
end
|
76
|
+
|
77
|
+
new_child.should == child
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
it "should build new child if asked" do
|
82
|
+
new_child = dummy.build_child
|
83
|
+
new_child.should be_new
|
84
|
+
new_child.should be_a(Child)
|
85
|
+
dummy.children
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should create a new child if asked" do
|
89
|
+
new_child = nil
|
90
|
+
stub_post_response(child) do
|
91
|
+
new_child = dummy.create_child
|
92
|
+
end
|
93
|
+
|
94
|
+
new_child.should_not be_new
|
95
|
+
new_child.should be_cached
|
96
|
+
dummy.children.should include(new_child)
|
97
|
+
Dummy.cache.flush
|
98
|
+
dummy.children.should include(new_child)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Amfetamine::RestHelpers do
|
4
|
+
context "methods" do
|
5
|
+
|
6
|
+
it "plural_path" do
|
7
|
+
Dummy.rest_path.should ==('/dummies')
|
8
|
+
end
|
9
|
+
|
10
|
+
it "singular_path" do
|
11
|
+
dummy = build(:dummy)
|
12
|
+
dummy.singular_path.should ==("/dummies/#{dummy.id}")
|
13
|
+
end
|
14
|
+
|
15
|
+
it "find_path" do
|
16
|
+
dummy = build(:dummy)
|
17
|
+
Dummy.find_path(dummy.id).should ==("/dummies/#{dummy.id}")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should work with a resource suffix" do
|
21
|
+
Dummy.resource_suffix = '.json'
|
22
|
+
Dummy.rest_path.should ==('/dummies.json')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "test_helpers" do
|
4
|
+
let(:test_dummy) { build(:dummy) }
|
5
|
+
describe "#prevent_external_connections!" do
|
6
|
+
it "should raise exception if connections are tried to be made" do
|
7
|
+
Dummy.prevent_external_connections!
|
8
|
+
lambda { Dummy.all }.should raise_exception(Amfetamine::ExternalConnectionsNotAllowed)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return correct objects if responses are stubbed for #singular" do
|
12
|
+
dummy = build(:dummy)
|
13
|
+
|
14
|
+
Dummy.stub_responses! do |res|
|
15
|
+
res.get { dummy }
|
16
|
+
end
|
17
|
+
|
18
|
+
Dummy.find(dummy.id).should == dummy
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return correct objects if responses are stubbed for #all" do
|
22
|
+
dummy = build(:dummy)
|
23
|
+
|
24
|
+
Dummy.stub_responses! do |res|
|
25
|
+
res.get { [dummy] }
|
26
|
+
end
|
27
|
+
|
28
|
+
Dummy.all.should == [dummy]
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return give me correct response codes" do
|
32
|
+
Dummy.stub_responses! do |res|
|
33
|
+
res.post(:code => 201) { }
|
34
|
+
end
|
35
|
+
|
36
|
+
dummy = Dummy.new(:title => 'valid', :description => 'valid')
|
37
|
+
dummy.valid?.should be_true
|
38
|
+
dummy.save.should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should also work with multiple paths" do
|
42
|
+
dummy = build(:dummy)
|
43
|
+
|
44
|
+
Dummy.stub_responses! do |res|
|
45
|
+
res.get(:code => 200, :path => '/dummies/1') { dummy }
|
46
|
+
res.get(:code => 200, :path => '/dummies/') { [ dummy ] }
|
47
|
+
end
|
48
|
+
|
49
|
+
Dummy.find(1).should == dummy
|
50
|
+
Dummy.all.should == [dummy]
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
it "should work with a let statement" do
|
55
|
+
lambda {
|
56
|
+
Dummy.stub_responses! do |res|
|
57
|
+
res.get { test_dummy }
|
58
|
+
res.get(:path => '/dummies') { [test_dummy] }
|
59
|
+
end
|
60
|
+
}.should_not raise_exception
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should work with opts parsed and descriminate #all" do
|
64
|
+
dummy1 = build(:dummy)
|
65
|
+
dummy2 = build(:dummy)
|
66
|
+
|
67
|
+
dummy1.title = "DUMMY1"
|
68
|
+
dummy2.title = "DUMMY2"
|
69
|
+
|
70
|
+
Dummy.stub_responses! do |r|
|
71
|
+
r.get(:path => '/dummies', :query => {:title => "DUMMY1"}) { [dummy1] }
|
72
|
+
r.get(:path => '/dummies', :query => {:title => "DUMMY2"}) { [dummy2] }
|
73
|
+
end
|
74
|
+
|
75
|
+
Dummy.all(:conditions => {:title => "DUMMY1"}).should include(dummy1)
|
76
|
+
Dummy.all(:conditions => {:title => "DUMMY1"}).should_not include(dummy2)
|
77
|
+
|
78
|
+
Dummy.all(:conditions => {:title => "DUMMY2"}).should include(dummy2)
|
79
|
+
Dummy.all(:conditions => {:title => "DUMMY2"}).should_not include(dummy1)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should work with opts parsed and descriminate #all" do
|
83
|
+
dummy1 = build(:dummy)
|
84
|
+
dummy2 = build(:dummy)
|
85
|
+
|
86
|
+
dummy1.title = "DUMMY1"
|
87
|
+
dummy2.title = "DUMMY2"
|
88
|
+
|
89
|
+
Dummy.stub_responses! do |r|
|
90
|
+
r.get(:path => "/dummies/#{dummy1.id}", :query => {:title => "DUMMY1"}) { dummy1 }
|
91
|
+
r.get(:path => "/dummies/#{dummy2.id}", :query => {:title => "DUMMY2"}) { dummy2 }
|
92
|
+
end
|
93
|
+
|
94
|
+
Dummy.find(dummy1.id, :conditions => {:title => "DUMMY1"}).should ==(dummy1)
|
95
|
+
Dummy.find(dummy1.id, :conditions => {:title => "DUMMY1"}).should_not ==(dummy2)
|
96
|
+
|
97
|
+
Dummy.find(dummy2.id, :conditions => {:title => "DUMMY2"}).should ==(dummy2)
|
98
|
+
Dummy.find(dummy2.id, :conditions => {:title => "DUMMY2"}).should_not ==(dummy1)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|