couchobject 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,143 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe CouchObject::Database do
4
+ before(:each) do
5
+ @server = mock("Couch server")
6
+ @uri = "http://localhost:8888"
7
+ @response = mock("Net::HTTP::Response")
8
+ CouchObject::Server.should_receive(:new).with(@uri).and_return(@server)
9
+ @response.stub!(:code).and_return(200)
10
+ @response.stub!(:body).and_return("[\"db1\", \"db2\"]")
11
+ @document_response = {
12
+ "_id" => "123BAC",
13
+ "_rev" => "946B7D1C",
14
+ "attributes" => {
15
+ "wheels" => 3
16
+ }
17
+ }
18
+ end
19
+
20
+ it "should create a database" do
21
+ @server.should_receive(:put).with("/foo", "").and_return(@response)
22
+ CouchObject::Database.create!(@uri, "foo")
23
+ end
24
+
25
+ it "should delete a database" do
26
+ @server.should_receive(:delete).with("/foo").and_return(@response)
27
+ CouchObject::Database.delete!(@uri, "foo")
28
+ end
29
+
30
+ it "should get all databases" do
31
+ @server.should_receive(:get).with("/_all_dbs").and_return(@response)
32
+ CouchObject::Database.all_databases(@uri)
33
+ end
34
+
35
+ it "should return all databases as an array" do
36
+ @server.should_receive(:get).with("/_all_dbs").and_return(@response)
37
+ dbs = CouchObject::Database.all_databases(@uri)
38
+ dbs.should == ["db1", "db2"]
39
+ end
40
+
41
+ it "should open a connection to the server" do
42
+ db = CouchObject::Database.new(@uri, "foo")
43
+ db.server.should == @server
44
+ end
45
+
46
+ it "should have a name" do
47
+ db = CouchObject::Database.new(@uri, "foo")
48
+ db.name.should == "foo"
49
+ end
50
+
51
+ it "should lint the database name from slashes with ::open" do
52
+ db = CouchObject::Database.open("http://localhost:8888/foo")
53
+ class << db
54
+ attr_accessor :dbname
55
+ end
56
+ db.dbname.should == "foo"
57
+ end
58
+
59
+ it "should GET" do
60
+ db = CouchObject::Database.new(@uri, "foo")
61
+ @server.should_receive(:get).with("/foo/123").and_return(@response)
62
+ db.get("123")
63
+ end
64
+
65
+ it "should POST" do
66
+ db = CouchObject::Database.new(@uri, "foo")
67
+ @server.should_receive(:post).with("/foo/123", "postdata").and_return(@response)
68
+ db.post("123", "postdata")
69
+ end
70
+
71
+ it "should PUT" do
72
+ db = CouchObject::Database.new(@uri, "foo")
73
+ @server.should_receive(:put).with("/foo/123", "postdata").and_return(@response)
74
+ db.put("123", "postdata")
75
+ end
76
+
77
+ it "should DELETE" do
78
+ db = CouchObject::Database.new(@uri, "foo")
79
+ @server.should_receive(:delete).with("/foo/123").and_return(@response)
80
+ db.delete("123")
81
+ end
82
+
83
+ it "should open a new connection from a full uri spec" do
84
+ proc{ CouchObject::Database.open("http://localhost:8888/foo") }.should_not raise_error
85
+ end
86
+
87
+ it "should know the database name" do
88
+ db = CouchObject::Database.new(@uri, "foo")
89
+ db.name.should == "foo"
90
+ end
91
+
92
+ it "should know the full uri" do
93
+ db = CouchObject::Database.new(@uri, "foo")
94
+ db.url.should == "http://localhost:8888/foo"
95
+ end
96
+
97
+ it "should load a document from id with #[]" do
98
+ db = CouchObject::Database.new(@uri, "foo")
99
+ db.should_receive(:get).with("123").twice.and_return(@document_response)
100
+ proc{ db["123"] }.should_not raise_error
101
+ db["123"].should == @document_response
102
+ end
103
+
104
+ it "should accept symbols for #[] too" do
105
+ db = CouchObject::Database.new(@uri, "foo")
106
+ db.should_receive(:get).with("foo").and_return(@document_response)
107
+ db[:foo]
108
+ end
109
+
110
+ it "should get a document by id" do
111
+ db = CouchObject::Database.new(@uri, "foo")
112
+ db.should_receive(:get).with("foo").twice.and_return(@document_response)
113
+ proc{ db.document("foo") }.should_not raise_error
114
+ db.document("foo").should == @document_response
115
+ end
116
+
117
+ it "should get a document by id and revision" do
118
+ db = CouchObject::Database.new(@uri, "foo")
119
+ db.should_receive(:get).with("foo?rev=123").twice.and_return(@document_response)
120
+ proc{ db.document("foo", "123") }.should_not raise_error
121
+ db.document("foo", "123").should == @document_response
122
+ end
123
+
124
+ it "should query the view" do
125
+ db = CouchObject::Database.new(@uri, "foo")
126
+ CouchObject::View.should_receive(:new).with(db, "myview").and_return(view = mock("View mock"))
127
+ view.should_receive(:query).and_return(nil)
128
+ db.views("myview")
129
+ end
130
+
131
+ it "should get a list of all documents" do
132
+ db = CouchObject::Database.new(@uri, "foo")
133
+ resp = mock("response")
134
+ resp.stub!(:body).and_return(JSON.unparse("rows" => [{"_rev"=>123, "_id"=>"123ABC"}]))
135
+ resp.stub!(:to_document).and_return(
136
+ CouchObject::Document.new("rows" => [{"_rev"=>123, "_id"=>"123ABC"}])
137
+ )
138
+ db.should_receive(:get).with("_all_docs").and_return(resp)
139
+ db.all_documents.should == [{"_rev"=>123, "_id"=>"123ABC"}]
140
+ end
141
+
142
+ #it "should url encode paths"
143
+ end
@@ -0,0 +1,142 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe CouchObject::Document do
4
+
5
+ before(:each) do
6
+ @db = mock("CouchObject::Database mock")
7
+ @test_data = {
8
+ "_id" => "123",
9
+ "_rev" => "666",
10
+ "foo" => "bar",
11
+ "baz" => {"quux" => [1,2,3]},
12
+ }
13
+ @response = mock("Response mock")
14
+ @response.stub!(:code).and_return(200)
15
+ @response.stub!(:body).and_return("")
16
+ @response.stub!(:to_document).and_return(CouchObject::Document.new(@test_data))
17
+ end
18
+
19
+ it "should initialize with a bunch of attributes" do
20
+ doc = CouchObject::Document.new({"foo" => "bar"})
21
+ doc.attributes.should == {"foo" => "bar"}
22
+ end
23
+
24
+ it "should have an id from the attributes" do
25
+ doc = CouchObject::Document.new(@test_data)
26
+ doc.id.should == @test_data["_id"]
27
+ end
28
+
29
+ it "should not have an id if not in attributes" do
30
+ doc = CouchObject::Document.new
31
+ doc.id.should == nil
32
+ end
33
+
34
+ it "should have an assignable id if new document" do
35
+ doc = CouchObject::Document.new
36
+ doc.id = "fubar"
37
+ doc.id.should == "fubar"
38
+ end
39
+
40
+ it "should should be new? if there's an id attribute" do
41
+ doc = CouchObject::Document.new(@test_data)
42
+ doc.new?.should == false
43
+ end
44
+
45
+ it "should not be new if there's not original id" do
46
+ doc = CouchObject::Document.new({"foo" => "bar"})
47
+ doc.new?.should == true
48
+ end
49
+
50
+ it "should be Enumerable on its attributes" do
51
+ CouchObject::Document.constants.should include("Enumerator")
52
+ doc = CouchObject::Document.new(@test_data)
53
+ doc.attributes.should_receive(:each)
54
+ doc.map {|attrib| attrib }
55
+ end
56
+
57
+ it "should be JSONable" do
58
+ doc = CouchObject::Document.new({"foo" => "bar"})
59
+ doc.to_json.should == JSON.unparse({"foo" => "bar"})
60
+ end
61
+
62
+ it "should be JSONable and include _id if id= is set" do
63
+ doc = CouchObject::Document.new({"foo" => "bar"})
64
+ doc.id = "quux"
65
+ doc.to_json.should == JSON.unparse({"foo" => "bar", "_id" => "quux"})
66
+ end
67
+
68
+ it "should POST to the database with create" do
69
+ doc = CouchObject::Document.new({"foo" => "bar"})
70
+ @db.should_receive(:post).with("", doc.to_json).and_return(@response)
71
+ doc.save(@db)
72
+ end
73
+
74
+ it "should PUT to the database with create" do
75
+ doc = CouchObject::Document.new(@test_data)
76
+ doc.should_receive(:to_json).and_return("JSON")
77
+ @db.should_receive(:put).with(@test_data["_id"], "JSON").and_return(@response)
78
+ doc.save(@db)
79
+ end
80
+
81
+ it "should send the current revision along when updating a doc" do
82
+ doc = CouchObject::Document.new(@test_data)
83
+ @db.should_receive(:put).and_return(@response)
84
+ doc.should_receive(:to_json).with("_rev" => doc.revision)
85
+ doc.save(@db)
86
+ end
87
+
88
+ it "should update its id when saving" do
89
+ @test_data.delete("_id")
90
+ @test_data.delete("_rev")
91
+ doc = CouchObject::Document.new(@test_data)
92
+ @db.should_receive(:post).and_return(@response)
93
+ doc.id.should be(nil)
94
+ doc.new?.should == true
95
+ doc.save(@db)
96
+ doc.id.should_not be(nil)
97
+ end
98
+
99
+ it "should have a revision" do
100
+ doc = CouchObject::Document.new(@test_data)
101
+ doc.revision.should == @test_data["_rev"]
102
+ end
103
+
104
+ it "should lookup document attributes with []" do
105
+ doc = CouchObject::Document.new({"foo" => "bar"})
106
+ doc["foo"].should == "bar"
107
+ end
108
+
109
+ it "should assign document attributes witih []=" do
110
+ doc = CouchObject::Document.new
111
+ doc["foo"].should == nil
112
+ doc["foo"] = "bar"
113
+ doc["foo"].should == "bar"
114
+ end
115
+
116
+ it "should delegate missing methods to attributes" do
117
+ doc = CouchObject::Document.new({"foo" => "bar", "stuff" => true })
118
+ doc.foo.should == "bar"
119
+ doc.stuff?.should == true
120
+ proc{ doc.foo = "baz" }.should_not raise_error
121
+ doc.foo.should == "baz"
122
+ end
123
+
124
+ it "should know if it has a given document key" do
125
+ doc = CouchObject::Document.new({"foo" => "bar"})
126
+ doc.has_key?("foo").should == true
127
+ doc.has_key?("bar").should == false
128
+ end
129
+
130
+ it "should know if it reponds to a key in the attributes" do
131
+ doc = CouchObject::Document.new({"foo" => "bar", "baz" => true})
132
+ doc.respond_to?(:foo).should == true
133
+ doc.respond_to?(:bar).should == false
134
+
135
+ doc.respond_to?(:baz?).should == true
136
+ doc.respond_to?(:bar?).should == false
137
+
138
+ doc.respond_to?(:foo=).should == true
139
+ doc.respond_to?(:bar=).should == false
140
+ end
141
+
142
+ end
@@ -0,0 +1,78 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+ require File.dirname(__FILE__) + "/integration_helper"
3
+
4
+ describe "Database operations" do
5
+ include IntegrationSpecHelper
6
+
7
+ before(:each) do
8
+ delete_test_db
9
+ end
10
+
11
+ it "should create a database " do
12
+ all_dbs = proc{ CouchObject::Database.all_databases("http://localhost:8888") }
13
+ all_dbs.call.include?("couchobject_test").should == false
14
+
15
+ create_test_db.should == {"ok" => true}
16
+
17
+ all_dbs.call.include?("couchobject_test").should == true
18
+ end
19
+
20
+ it "should delete a database" do
21
+ all_dbs = proc{ CouchObject::Database.all_databases("http://localhost:8888") }
22
+ all_dbs.call.include?("couchobject_test").should == false
23
+
24
+ create_test_db.should == {"ok" => true}
25
+ CouchObject::Database.delete!(
26
+ "http://localhost:8888",
27
+ "couchobject_test"
28
+ ).should == {"ok" => true}
29
+
30
+ all_dbs.call.include?("couchobject_test").should == false
31
+ end
32
+
33
+ it "should open a db connection and know the dbname and uri" do
34
+ db = open_test_db
35
+ db.name.should == "couchobject_test"
36
+ db.url.should == "http://localhost:8888/couchobject_test"
37
+ end
38
+
39
+ it "should GET a non existing document and return 404" do
40
+ db = open_test_db
41
+ response = db.get("roflcopters")
42
+ response.code.should == 404
43
+ end
44
+
45
+ it "should POST a new document successfully" do
46
+ db = create_and_open_test_db
47
+ response = db.post("", JSON.unparse({"foo" => ["bar", "baz"]}))
48
+ doc = response.to_document
49
+ doc.ok?.should == true
50
+ doc.id.should_not == nil
51
+ end
52
+
53
+ it "should PUT to update and existing document" do
54
+ db = create_and_open_test_db
55
+ response = db.post("", JSON.unparse({"foo" => ["bar", "baz"]}))
56
+ created_doc = response.to_document
57
+ response = db.put(created_doc.id, JSON.unparse(
58
+ {"foo" => [1, 2]}.merge("_rev" => created_doc.revision)
59
+ ))
60
+ response.to_document.ok?.should == true
61
+
62
+ updated_doc = db.get(created_doc.id).to_document
63
+ updated_doc.foo.should == [1,2]
64
+ end
65
+
66
+ it "should DELETE to delete an existing document" do
67
+ db = create_and_open_test_db
68
+ response = db.post("", JSON.unparse({"foo" => ["bar", "baz"]}))
69
+ created_doc = response.to_document
70
+
71
+ resp = db.delete(created_doc.id)
72
+ resp.code.should == 202
73
+
74
+ resp = db.get(created_doc.id)
75
+ resp.code.should == 404
76
+ end
77
+
78
+ end
@@ -0,0 +1,41 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+ require File.dirname(__FILE__) + "/integration_helper"
3
+
4
+ describe "Document functionality" do
5
+ include IntegrationSpecHelper
6
+
7
+ before(:each) do
8
+ delete_test_db
9
+ @db = create_and_open_test_db
10
+ end
11
+
12
+ it "should create our document" do
13
+ doc = CouchObject::Document.new("foo" => [1,2])
14
+ resp = doc.save(@db)
15
+ resp.code.should == 201
16
+ @db.get(doc.id).code.should == 200
17
+ end
18
+
19
+ it "should update a document" do
20
+ doc = CouchObject::Document.new("foo" => [1,2])
21
+ resp = doc.save(@db)
22
+ resp.code.should == 201
23
+
24
+ doc = @db.get(doc.id).to_document
25
+ doc.foo = "bar"
26
+ doc.save(@db).parsed_body["ok"].should == true
27
+
28
+ doc = @db.get(doc.id).to_document
29
+ doc.foo.should == "bar"
30
+ end
31
+
32
+ it "should update itself properly" do
33
+ doc = CouchObject::Document.new("foo" => [1,2])
34
+ doc.save(@db)
35
+ @db.all_documents.size.should == 1
36
+ doc.foo = "bar"
37
+ doc.save(@db)
38
+ @db.all_documents.size.should == 1
39
+ end
40
+
41
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ module IntegrationSpecHelper
4
+ def create_test_db(name="couchobject_test")
5
+ CouchObject::Database.create!("http://localhost:8888", name)
6
+ end
7
+
8
+ def open_test_db(name="couchobject_test")
9
+ CouchObject::Database.open("http://localhost:8888/#{name}")
10
+ end
11
+
12
+ def delete_test_db(name="couchobject_test")
13
+ CouchObject::Database.delete!("http://localhost:8888", "couchobject_test")
14
+ end
15
+
16
+ def create_and_open_test_db(name="couchobject_test")
17
+ create_test_db(name)
18
+ open_test_db(name)
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe CouchObject::Model do
4
+
5
+ end
@@ -0,0 +1,91 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ class Bike
4
+ include CouchObject::Persistable
5
+
6
+ def initialize
7
+ @wheels = 2
8
+ end
9
+ attr_accessor :wheels
10
+
11
+ def to_couch
12
+ {:wheels => @wheels}
13
+ end
14
+
15
+ def self.from_couch(attributes)
16
+ bike = new
17
+ bike.wheels = attributes["wheels"]
18
+ bike
19
+ end
20
+ end
21
+
22
+ describe CouchObject::Persistable, "when mixed into a Class" do
23
+ before(:each) do
24
+ @bike = Bike.new
25
+ @db = mock("mock db")
26
+
27
+ @empty_response = {}
28
+ @ok_response = {"ok" => true}
29
+ @document_response = {
30
+ "_id" => "123BAC",
31
+ "_rev" => "946B7D1C",
32
+ "attributes" => {
33
+ "wheels" => 3
34
+ }
35
+ }
36
+ end
37
+
38
+ it "should give the class a save method that saves the object" do
39
+ CouchObject::Database.should_receive(:open).and_return(@db)
40
+ @db.should_receive(:post).with("", @bike.to_json).and_return(@empty_response)
41
+ @bike.save("foo")
42
+ end
43
+
44
+ it "should raise if no to_couch on class" do
45
+ klass = Class.new{ include CouchObject::Persistable }
46
+ proc{ klass.new.to_json }.should raise_error(CouchObject::Persistable::NoToCouchMethodError)
47
+ end
48
+
49
+ it "should raise if no to_couch on class" do
50
+ klass = Class.new{
51
+ include CouchObject::Persistable
52
+ def to_couch() end
53
+ }
54
+ proc{ klass.get_by_id("foo", "bar") }.should raise_error(CouchObject::Persistable::NoFromCouchMethodError)
55
+ end
56
+
57
+ it "should return the doc id on successfull save" do
58
+ CouchObject::Database.should_receive(:open).and_return(@db)
59
+ @db.should_receive(:post).with("", @bike.to_json).and_return(@document_response)
60
+ @bike.save("foo")["_id"].should == "123BAC"
61
+ end
62
+
63
+ it "should assign the returned id to itself on successful save" do
64
+ CouchObject::Database.should_receive(:open).and_return(@db)
65
+ @db.should_receive(:post).with("", @bike.to_json).and_return(@document_response)
66
+ @bike.save("foo")
67
+ @bike.id.should == "123BAC"
68
+ end
69
+
70
+ it "should know if itself is a new object" do
71
+ CouchObject::Database.should_receive(:open).and_return(@db)
72
+ @db.should_receive(:post).with("", @bike.to_json).and_return(@document_response)
73
+ @bike.new?.should == true
74
+ @bike.save("foo")
75
+ @bike.new?.should == false
76
+ end
77
+
78
+ it "should get document by id" do
79
+ CouchObject::Database.should_receive(:open).and_return(@db)
80
+ @db.should_receive(:get).with("123BAC").and_return(@document_response)
81
+ Bike.get_by_id("foo", "123BAC")
82
+ end
83
+
84
+ it "should instantiate a new object based on their #to_couch" do
85
+ CouchObject::Database.should_receive(:open).and_return(@db)
86
+ @db.should_receive(:get).with("123BAC").and_return(@document_response)
87
+ bike = Bike.get_by_id("foo", "123BAC")
88
+ bike.class.should == Bike
89
+ bike.wheels.should == 3
90
+ end
91
+ end