couchdb 0.1.0

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.
@@ -0,0 +1,22 @@
1
+
2
+ module CouchDB
3
+
4
+ # The Row class acts as a wrapper for a CouchDB view result row.
5
+ class Row
6
+
7
+ attr_reader :database
8
+ attr_reader :id
9
+ attr_reader :key
10
+ attr_reader :value
11
+
12
+ def initialize(database, attributes = { })
13
+ @database, @id, @key, @value, @document = database, *attributes.values_at("id", "key", "value", "doc")
14
+ end
15
+
16
+ def document
17
+ Document.new @database, @document
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,42 @@
1
+
2
+ module CouchDB
3
+
4
+ # The Server class provides methods to retrieve informations and statistics
5
+ # of a CouchDB server.
6
+ class Server
7
+
8
+ attr_reader :host
9
+ attr_reader :port
10
+
11
+ def initialize(host = "localhost", port = 5984)
12
+ @host, @port = host, port
13
+ end
14
+
15
+ def ==(other)
16
+ other.is_a?(self.class) && @host == other.host && @port == other.port
17
+ end
18
+
19
+ def information
20
+ Transport::JSON.request :get, url + "/", :expected_status_code => 200
21
+ end
22
+
23
+ def statistics
24
+ Transport::JSON.request :get, url + "/_stats", :expected_status_code => 200
25
+ end
26
+
27
+ def database_names
28
+ Transport::JSON.request :get, url + "/_all_dbs", :expected_status_code => 200
29
+ end
30
+
31
+ def uuids(count = 1)
32
+ response = Transport::JSON.request :get, url + "/_uuids", :expected_status_code => 200, :parameters => { :count => count }
33
+ response["uuids"]
34
+ end
35
+
36
+ def url
37
+ "http://#{@host}:#{@port}"
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Database do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = described_class.new @server, "test"
8
+ end
9
+
10
+ describe "create!" do
11
+
12
+ before :each do
13
+ @database.delete_if_exists!
14
+ end
15
+
16
+ it "should create the database" do
17
+ @database.create!
18
+ @database.exists?.should be_true
19
+ end
20
+
21
+ end
22
+
23
+ describe "delete!" do
24
+
25
+ before :each do
26
+ @database.create_if_missing!
27
+ end
28
+
29
+ it "should delete the database" do
30
+ @database.delete!
31
+ @database.exists?.should be_false
32
+ end
33
+
34
+ end
35
+
36
+ describe "information" do
37
+
38
+ before :each do
39
+ @database.create_if_missing!
40
+ end
41
+
42
+ it "should return information about the database" do
43
+ @database.information.should be_instance_of(Hash)
44
+ end
45
+
46
+ end
47
+
48
+ describe "documents" do
49
+
50
+ it "should return a collection" do
51
+ @database.documents.should be_instance_of(CouchDB::Collection)
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,78 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Document do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = CouchDB::Database.new @server, "test"
8
+ @database.delete_if_exists!
9
+ @database.create_if_missing!
10
+
11
+ @document = described_class.new @database, "_id" => "test_document_1", "test" => "test value"
12
+ @document.save
13
+ end
14
+
15
+ after :each do
16
+ @document.destroy
17
+ end
18
+
19
+ describe "load" do
20
+
21
+ it "should load the document's properties" do
22
+ @document["test"] = nil
23
+ @document.load
24
+ @document["test"].should == "test value"
25
+ end
26
+
27
+ end
28
+
29
+ describe "save" do
30
+
31
+ context "on a new model" do
32
+
33
+ before :each do
34
+ begin
35
+ @document.load
36
+ @document.destroy
37
+ rescue described_class::NotFoundError
38
+ end
39
+ end
40
+
41
+ it "should create the document" do
42
+ lambda do
43
+ @document.save
44
+ end.should change(@document, :new?).from(true).to(false)
45
+ end
46
+
47
+ end
48
+
49
+ context "on an existing model" do
50
+
51
+ it "should update the document" do
52
+ lambda do
53
+ @document["test"] = "another test value"
54
+ @document.save
55
+ end.should change(@document, :rev)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+
62
+ describe "destroy" do
63
+
64
+ it "should destroy the document" do
65
+ lambda do
66
+ @document.destroy
67
+ end.should change(@document, :exists?).from(true).to(false)
68
+ end
69
+
70
+ it "should set the document's state to new" do
71
+ lambda do
72
+ @document.destroy
73
+ end.should change(@document, :new?).from(false).to(true)
74
+ end
75
+
76
+ end
77
+
78
+ end
@@ -0,0 +1,43 @@
1
+ require File.join(File.dirname(__FILE__), "..", "spec_helper")
2
+
3
+ describe CouchDB::Server do
4
+
5
+ before :each do
6
+ @server = described_class.new
7
+ end
8
+
9
+ describe "information" do
10
+
11
+ it "should return some information about the server" do
12
+ @server.information.should == { "couchdb" => "Welcome", "version" => "1.0.1" }
13
+ end
14
+
15
+ end
16
+
17
+ describe "statistics" do
18
+
19
+ it "should return some statistics about the server" do
20
+ @server.statistics.should be_instance_of(Hash)
21
+ end
22
+
23
+ end
24
+
25
+ describe "database_names" do
26
+
27
+ it "should return the names of all databases" do
28
+ @server.database_names.should be_instance_of(Array)
29
+ end
30
+
31
+ end
32
+
33
+ describe "uuids" do
34
+
35
+ it "should return the given number of generated uuids" do
36
+ uuids = @server.uuids 4
37
+ uuids.should be_instance_of(Array)
38
+ uuids.size.should == 4
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,49 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
+
3
+ describe "views" do
4
+
5
+ before :each do
6
+ @server = CouchDB::Server.new
7
+ @database = CouchDB::Database.new @server, "test"
8
+ @database.delete_if_exists!
9
+ @database.create_if_missing!
10
+
11
+ @document_one = CouchDB::Document.new @database, "_id" => "test_document_1", "category" => "one"
12
+ @document_one.save
13
+ @document_two = CouchDB::Document.new @database, "_id" => "test_document_2", "category" => "two"
14
+ @document_two.save
15
+
16
+ @design = CouchDB::Design.new @database, "design_1"
17
+ @view = CouchDB::Design::View.new @design, "view_1",
18
+ "function(document) { emit([ document['category'], document['_id'] ]); }"
19
+ @design.save
20
+ end
21
+
22
+ describe "collection" do
23
+
24
+ it "should return a collection including the right rows" do
25
+ collection = @view.collection :startkey => [ "one", nil ], :endkey => [ "one", { } ]
26
+ collection.size.should == 1
27
+ collection[0].id.should == "test_document_1"
28
+ collection[0].key.should == [ "one", "test_document_1" ]
29
+ collection[0].value.should be_nil
30
+ end
31
+
32
+ it "should return a collection including the right documents" do
33
+ collection = @view.collection :startkey => [ "one", nil ], :endkey => [ "one", { } ]
34
+ collection.documents.should include(@document_one)
35
+ collection.documents.should_not include(@document_two)
36
+ end
37
+
38
+ end
39
+
40
+ describe "all documents collection" do
41
+
42
+ it "should return a collection with all documents of the database" do
43
+ collection = @database.documents
44
+ collection.size.should == 3 # two documents plus the design
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,121 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe CouchDB::Collection do
4
+
5
+ before :each do
6
+ Transport::JSON.stub(:request)
7
+ @database = mock CouchDB::Database
8
+
9
+ @collection = described_class.new @database, "http://host:1234/test/_all_docs"
10
+ end
11
+
12
+ describe "initialize" do
13
+
14
+ it "should set the database" do
15
+ @collection.database.should == @database
16
+ end
17
+
18
+ it "should set the url" do
19
+ @collection.url.should == "http://host:1234/test/_all_docs"
20
+ end
21
+
22
+ end
23
+
24
+ describe "total_count" do
25
+
26
+ before :each do
27
+ Transport::JSON.stub(:request).and_return({ "total_rows" => 1 })
28
+ end
29
+
30
+ describe "without a previously performed fetch" do
31
+
32
+ it "should perform a meta fetch (with a limit of zero)" do
33
+ Transport::JSON.should_receive(:request).with(
34
+ :get,
35
+ "http://host:1234/test/_all_docs",
36
+ :parameters => { :limit => 0 },
37
+ :encode_parameters => true,
38
+ :expected_status_code => 200
39
+ ).and_return({ "total_rows" => 1 })
40
+ @collection.total_count
41
+ end
42
+
43
+ it "should return the total count" do
44
+ @collection.total_count.should == 1
45
+ end
46
+
47
+ end
48
+
49
+ describe "with a previously performed fetch" do
50
+
51
+ before :each do
52
+ @collection.first # perform the fetch
53
+ end
54
+
55
+ it "should not perform another fetch" do
56
+ Transport::JSON.should_not_receive(:request)
57
+ @collection.total_count
58
+ end
59
+
60
+ it "should return the total count" do
61
+ @collection.total_count.should == 1
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+ describe "first" do
69
+
70
+ before :each do
71
+ @row_hash = mock Hash
72
+ Transport::JSON.stub(:request).and_return({
73
+ "total_rows" => 1,
74
+ "rows" => [ @row_hash ]
75
+ })
76
+ @row = mock CouchDB::Row
77
+ CouchDB::Row.stub(:new).and_return(@row)
78
+ end
79
+
80
+ it "should initialize the row with the row hash" do
81
+ CouchDB::Row.should_receive(:new).with(@database, @row_hash).and_return(@row)
82
+ @collection.first
83
+ end
84
+
85
+ it "should return the first element of the fetched result" do
86
+ @collection.first.should == @row
87
+ end
88
+
89
+ it "should update the total count" do
90
+ @collection.first
91
+ @collection.total_count.should == 1
92
+ end
93
+
94
+ end
95
+
96
+ describe "documents" do
97
+
98
+ before :each do
99
+ @document = mock CouchDB::Document
100
+ @row = mock CouchDB::Row, :document => @document
101
+ @collection.stub(:map).and_yield(@row).and_return([ @document ])
102
+ end
103
+
104
+ it "should add the include docs options" do
105
+ @collection.documents.first
106
+ @collection.options.should include(:include_docs => true)
107
+ end
108
+
109
+ it "should map the rows to documents" do
110
+ @collection.should_receive(:map).and_yield(@row).and_return([ @document ])
111
+ @collection.documents.first
112
+ end
113
+
114
+ it "should return the selected row's document" do
115
+ document = @collection.documents.first
116
+ document.should == @document
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "spec_helper"))
2
+
3
+ describe CouchDB::Database do
4
+
5
+ before :each do
6
+ Transport::JSON.stub(:request)
7
+ @server = mock CouchDB::Server, :url => "http://host:1234", :database_names => [ "test" ]
8
+
9
+ @database = CouchDB::Database.new @server, "test"
10
+ end
11
+
12
+ describe "==" do
13
+
14
+ it "should be true when comparing two equal databases" do
15
+ @database.should == described_class.new(@server, "test")
16
+ end
17
+
18
+ it "should be false when comparing two different databases" do
19
+ @database.should_not == described_class.new(@server, "different")
20
+ end
21
+
22
+ end
23
+
24
+ describe "===" do
25
+
26
+ it "should be true when comparing a database object with itself" do
27
+ @database.should === @database
28
+ end
29
+
30
+ it "should be false when comparing a database object with another database object" do
31
+ @database.should_not === described_class.new(@server, "test")
32
+ end
33
+
34
+ end
35
+
36
+ describe "create!" do
37
+
38
+ it "should request the create of the database" do
39
+ Transport::JSON.should_receive(:request).with(
40
+ :put,
41
+ "http://host:1234/test",
42
+ :expected_status_code => 201
43
+ )
44
+ @database.create!
45
+ end
46
+
47
+ end
48
+
49
+ describe "create_if_missing!" do
50
+
51
+ before :each do
52
+ @database.stub(:create!)
53
+ end
54
+
55
+ it "should not call create! if the database exists" do
56
+ @database.stub(:exists?).and_return(true)
57
+ @database.should_not_receive(:create!)
58
+ @database.create_if_missing!
59
+ end
60
+
61
+ it "should call create! if the database not exists" do
62
+ @database.stub(:exists?).and_return(false)
63
+ @database.should_receive(:create!)
64
+ @database.create_if_missing!
65
+ end
66
+
67
+ end
68
+
69
+ describe "delete!" do
70
+
71
+ it "should delete the database" do
72
+ Transport::JSON.should_receive(:request).with(
73
+ :delete,
74
+ "http://host:1234/test",
75
+ :expected_status_code => 200
76
+ )
77
+ @database.delete!
78
+ end
79
+
80
+ end
81
+
82
+ describe "delete_if_exists!" do
83
+
84
+ before :each do
85
+ @database.stub(:delete!)
86
+ end
87
+
88
+ it "should call delete! if the database exists" do
89
+ @database.stub(:exists?).and_return(true)
90
+ @database.should_receive(:delete!)
91
+ @database.delete_if_exists!
92
+ end
93
+
94
+ it "should not call delete! if the database not exists" do
95
+ @database.stub(:exists?).and_return(false)
96
+ @database.should_not_receive(:delete!)
97
+ @database.delete_if_exists!
98
+ end
99
+
100
+ end
101
+
102
+ describe "information" do
103
+
104
+ it "should request database information" do
105
+ Transport::JSON.should_receive(:request).with(
106
+ :get,
107
+ "http://host:1234/test",
108
+ :expected_status_code => 200
109
+ ).and_return("result")
110
+ @database.information.should == "result"
111
+ end
112
+
113
+ end
114
+
115
+ describe "exists?" do
116
+
117
+ it "should be true" do
118
+ @database.exists?.should be_true
119
+ end
120
+
121
+ it "should be false if no database with the given name exists" do
122
+ database = described_class.new @server, "invalid"
123
+ database.exists?.should be_false
124
+ end
125
+
126
+ end
127
+
128
+ describe "documents" do
129
+
130
+ it "should return a collection" do
131
+ collection = @database.documents
132
+ collection.should be_instance_of(CouchDB::Collection)
133
+ collection.url.should == "http://host:1234/test/_all_docs"
134
+ end
135
+
136
+ end
137
+
138
+ end