couchbase 0.9.7

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,9 @@
1
+ {
2
+ "_id": "_design/test_it_creates_design_doc_from_io",
3
+ "language": "javascript",
4
+ "views": {
5
+ "all": {
6
+ "map": "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
7
+ }
8
+ }
9
+ }
@@ -0,0 +1,39 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestBucket < MiniTest::Unit::TestCase
4
+ def setup
5
+ config_fixture = json_fixture('buckets-config.json')
6
+ Couchbase::Bucket.any_instance.stubs(:http_get).returns(config_fixture)
7
+ Couchbase::Bucket.class_eval do
8
+ alias :listen_for_config_changes_orig :listen_for_config_changes
9
+ define_method :listen_for_config_changes do
10
+ setup(config_fixture.first)
11
+ end
12
+ end
13
+ end
14
+
15
+ def teardown
16
+ Couchbase::Bucket.class_eval do
17
+ alias :listen_for_config_changes :listen_for_config_changes_orig
18
+ end
19
+ end
20
+
21
+ def test_it_should_defaults_to_default_bucket_in_production_mode
22
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
23
+ assert_equal 'default', bucket.name
24
+ assert_equal :production, bucket.environment
25
+ end
26
+
27
+ def test_it_should_initialize_itself_from_config
28
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
29
+ assert_equal 'http://localhost:8091/pools/default/buckets/default', bucket.uri.to_s
30
+ assert_equal 'membase', bucket.type
31
+ assert_equal 1, bucket.nodes.size
32
+ assert_equal 256, bucket.vbuckets.size
33
+ end
34
+
35
+ def test_initialization_low_level_drivers
36
+ bucket = Couchbase.new('http://localhost:8091/pools/default', :format => :plain)
37
+ assert_equal :plain, bucket.default_format
38
+ end
39
+ end
@@ -0,0 +1,9 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestCouchbase < MiniTest::Unit::TestCase
4
+ def test_that_it_create_instance_of_bucket
5
+ assert_instance_of Couchbase::Bucket, Couchbase.new('http://localhost:8091/pools/default')
6
+ end
7
+ end
8
+
9
+
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestCouchdb < MiniTest::Unit::TestCase
4
+ def setup
5
+ @bucket = Couchbase.new('http://localhost:8091/pools/default')
6
+ end
7
+
8
+ def test_that_it_could_connect_to_couchdb
9
+ server_uri = @bucket.next_node.couch_api_base[/http:\/\/[^\/]+/]
10
+ assert_equal %w(couchbase couchdb version), @bucket.http_get(server_uri).keys.sort
11
+ end
12
+
13
+ def test_that_it_raises_error_if_couch_api_isnt_implemented
14
+ bucket = Couchbase.new('http://localhost:8091/pools/default')
15
+ bucket.nodes.each{|node| node.couch_api_base = nil}
16
+ assert_raises(Couchbase::NotImplemented) do
17
+ bucket.design_docs
18
+ end
19
+ end
20
+
21
+ def test_that_it_could_create_doc_using_memcached_api
22
+ # cleanup
23
+ @bucket.delete(test_id) rescue Memcached::NotFound
24
+ @bucket.delete_design_doc(test_id)
25
+
26
+ @bucket[test_id] = {'msg' => 'hello world'}
27
+ @bucket.save_design_doc('_id' => "_design/#{test_id}",
28
+ 'views' => {'all' => {'map' => 'function(doc){if(doc.msg){emit(doc._id, doc.msg)}}'}})
29
+ assert_operation_completed { database_ready(@bucket) }
30
+ ddoc = @bucket.design_docs[test_id]
31
+ assert ddoc, "design document '_design/#{test_id}' not found"
32
+ doc = ddoc.all.detect{|doc| doc['id'] == test_id && doc['value'] == 'hello world'}
33
+ assert doc, "object '#{test_id}' not found"
34
+ end
35
+
36
+ def test_that_it_could_remove_design_doc
37
+ @bucket.delete_design_doc(test_id)
38
+ @bucket[test_id] = {'msg' => 'hello world'}
39
+ @bucket.save_design_doc('_id' => "_design/#{test_id}",
40
+ 'views' => {'all' => {'map' => 'function(doc){if(doc.msg){emit(doc._id, doc.msg)}}'}})
41
+ assert_operation_completed { database_ready(@bucket) }
42
+ ddoc = @bucket.design_docs[test_id]
43
+ assert ddoc, "design document '_design/#{test_id}' not found"
44
+ @bucket.delete_design_doc("_design/#{test_id}")
45
+ ddoc = @bucket.design_docs[test_id]
46
+ refute ddoc, "design document '_design/#{test_id}' still here"
47
+ end
48
+
49
+ def test_it_creates_design_doc_from_string
50
+ doc = <<-EOD
51
+ {
52
+ "_id": "_design/#{test_id}",
53
+ "language": "javascript",
54
+ "views": {
55
+ "all": {
56
+ "map": "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
57
+ }
58
+ }
59
+ }
60
+ EOD
61
+
62
+ @bucket.delete_design_doc(test_id)
63
+ @bucket.save_design_doc(doc)
64
+ assert_operation_completed { database_ready(@bucket) }
65
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
66
+ end
67
+
68
+ def test_it_creates_design_doc_from_io
69
+ doc = File.open(File.join(File.dirname(__FILE__), 'support', 'sample_design_doc.json'))
70
+ @bucket.delete_design_doc(test_id)
71
+ @bucket.save_design_doc(doc)
72
+ assert_operation_completed { database_ready(@bucket) }
73
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
74
+ end
75
+
76
+ def test_it_creates_design_doc_from_hash
77
+ doc = {
78
+ "_id" => "_design/#{test_id}",
79
+ "language" => "javascript",
80
+ "views" => {
81
+ "all" => {
82
+ "map" => "function(doc){ if(doc.msg){ emit(doc._id, doc.msg) } }"
83
+ }
84
+ }
85
+ }
86
+
87
+ @bucket.delete_design_doc(test_id)
88
+ @bucket.save_design_doc(doc)
89
+ assert_operation_completed { database_ready(@bucket) }
90
+ assert @bucket.design_docs[test_id], "design document '_design/#{test_id}' not found"
91
+ end
92
+
93
+ protected
94
+
95
+ def test_id
96
+ name = caller.first[/.*[` ](.*)'/, 1]
97
+ end
98
+ end
@@ -0,0 +1,11 @@
1
+ require 'minitest/autorun'
2
+ require 'couchbase'
3
+
4
+ class TestView < MiniTest::Unit::TestCase
5
+ def test_that_it_defines_views_for_design_documents_only
6
+ design_doc = Couchbase::Document.new(:mock, {'_id' => '_design/foo', 'views' => {'all' => {'map' => 'function(doc){}'}}})
7
+ assert_respond_to(design_doc, :all)
8
+ regular_doc = Couchbase::Document.new(:mock, {'_id' => 'foo', 'views' => {'all' => {'map' => 'function(doc){}'}}})
9
+ refute_respond_to(regular_doc, :all)
10
+ end
11
+ end
@@ -0,0 +1,88 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestLatch < MiniTest::Unit::TestCase
4
+ def test_properly_initialize
5
+ l = Couchbase::Latch.new(true, false)
6
+ assert_equal(true, l.state)
7
+ assert_equal(false, l.target)
8
+ end
9
+
10
+ def test_basic_latch_usage
11
+ latch = Couchbase::Latch.new(:dirty, :ready)
12
+ obj = "bar"
13
+ Thread.new do
14
+ obj = "foo"
15
+ latch.toggle
16
+ end
17
+ latch.wait
18
+ assert_equal(:ready, latch.state)
19
+ assert_equal("foo", obj)
20
+ end
21
+
22
+ def test_basic_latch_usage_inverted
23
+ latch = Couchbase::Latch.new(:dirty, :ready)
24
+ obj = "bar"
25
+ Thread.new do
26
+ latch.wait
27
+ assert_equal(:ready, latch.state)
28
+ assert_equal("foo", obj)
29
+ end
30
+ obj = "foo"
31
+ latch.toggle
32
+ end
33
+
34
+ def test_latch_with_identical_values_skips_wait
35
+ latch = Couchbase::Latch.new(:ready, :ready)
36
+ latch.wait
37
+ assert_equal(:ready, latch.state)
38
+ end
39
+
40
+ def test_toggle_with_two_chained_threads
41
+ latch = Couchbase::Latch.new(:start, :end)
42
+ name = "foo"
43
+ Thread.new do
44
+ Thread.new do
45
+ name = "bar"
46
+ latch.toggle
47
+ end
48
+ end
49
+ latch.wait
50
+ assert_equal(:end, latch.state)
51
+ assert_equal("bar", name)
52
+ end
53
+
54
+ def test_toggle_with_multiple_waiters
55
+ proceed_latch = Couchbase::Latch.new(:start, :end)
56
+ result = :bar
57
+ Thread.new do
58
+ proceed_latch.wait
59
+ assert_equal(:foo, result)
60
+ end
61
+ Thread.new do
62
+ proceed_latch.wait
63
+ assert_equal(:foo, result)
64
+ end
65
+ assert_equal(:bar, result)
66
+ proceed_latch.toggle
67
+ assert_equal(:end, proceed_latch.state)
68
+ end
69
+
70
+ def test_interleaved_latches
71
+ check_latch = Couchbase::Latch.new(:dirty, :ready)
72
+ change_1_latch = Couchbase::Latch.new(:dirty, :ready)
73
+ change_2_latch = Couchbase::Latch.new(:dirty, :ready)
74
+ name = "foo"
75
+ Thread.new do
76
+ name = "bar"
77
+ change_1_latch.toggle
78
+ check_latch.wait
79
+ name = "man"
80
+ change_2_latch.toggle
81
+ end
82
+ change_1_latch.wait
83
+ assert_equal("bar", name)
84
+ check_latch.toggle
85
+ change_2_latch.wait
86
+ assert_equal("man", name)
87
+ end
88
+ end
@@ -0,0 +1,59 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestMemcached < MiniTest::Unit::TestCase
4
+
5
+ def test_race_absence_during_initialization
6
+ session = connect
7
+ assert_raises(Memcached::NotFound) do
8
+ session.get(test_id)
9
+ end
10
+ end
11
+
12
+ def test_experimental_features_is_always_on
13
+ assert_respond_to connect, :touch
14
+ assert_respond_to connect(:experimental_features => false), :touch
15
+ assert_respond_to connect('experimental_features' => false), :touch
16
+ end
17
+
18
+ def test_single_get
19
+ session = connect
20
+ session.set(test_id, "foo")
21
+ assert "foo", session.get(test_id)
22
+ end
23
+
24
+ def test_single_get_missing
25
+ assert_raises(Memcached::NotFound) do
26
+ connect.get("missing-key")
27
+ end
28
+ end
29
+
30
+ def test_multi_get
31
+ session = connect
32
+ session.set(test_id(1), "foo")
33
+ session.set(test_id(2), "bar")
34
+ expected = {test_id(1) => "foo", test_id(2) => "bar"}
35
+ assert expected, session.get(test_id(1), test_id(2))
36
+ ids = [1, 2].map{|n| test_id(n)}
37
+ assert expected, session.get(ids)
38
+ end
39
+
40
+ def test_multi_get_missing
41
+ session = connect
42
+ session.set(test_id(1), "foo")
43
+ expected = {test_id(1) => "foo"}
44
+ assert expected, session.get(test_id(1), test_id(2))
45
+ ids = [1, 2].map{|n| test_id(n)}
46
+ assert expected, session.get(ids)
47
+ end
48
+
49
+ protected
50
+
51
+ def connect(options = {})
52
+ uri = options.delete(:pool_uri) || "http://localhost:8091/pools/default"
53
+ Couchbase.new(uri, options)
54
+ end
55
+
56
+ def test_id(suffix = nil)
57
+ "#{caller.first[/.*[` ](.*)'/, 1]}#{suffix}"
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ require 'minitest/autorun'
2
+ require 'couchbase'
3
+
4
+ class TestRestClient < MiniTest::Unit::TestCase
5
+ class RestClientMock
6
+ extend Couchbase::RestClient
7
+ end
8
+
9
+ def test_that_build_uri_duplicates_string
10
+ uri = "http://example.com/"
11
+ assert_equal "http://example.com/?foo=bar", RestClientMock.send(:build_query, uri, {'foo' => 'bar'})
12
+ assert_equal "http://example.com/", uri
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestVersion < MiniTest::Unit::TestCase
4
+ def test_that_it_defines_version
5
+ assert_match /\d+\.\d+(\.\d*)/, Couchbase::VERSION
6
+ end
7
+ end
@@ -0,0 +1,98 @@
1
+ require File.join(File.dirname(__FILE__), 'setup')
2
+
3
+ class TestView < MiniTest::Unit::TestCase
4
+ def test_pagination
5
+ connection = populate_database
6
+ view = connection.design_docs['test_view'].all
7
+
8
+ # fetch all records
9
+ collection = view.fetch(:limit => 10)
10
+ assert_equal 10, collection.size
11
+ assert_equal 100, collection.total_entries
12
+
13
+ # fetch with reduce
14
+ view = connection.design_docs['test_view'].sum
15
+ docs = view.fetch(:limit => 2, :group => true)
16
+ assert_equal 2, docs.size
17
+ assert_equal nil, docs.total_entries
18
+
19
+ assert_instance_of Couchbase::View, connection.all_docs
20
+ end
21
+
22
+ def test_when_stream_has_errors_it_raises_error_by_default
23
+ response = <<-EOR
24
+ {
25
+ "total_rows": 0,
26
+ "rows": [ ],
27
+ "errors": [
28
+ {
29
+ "from": "127.0.0.1:5984",
30
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_b`."
31
+ },
32
+ {
33
+ "from": "http:// localhost:5984/_view_merge/",
34
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_c`."
35
+ }
36
+ ]
37
+ }
38
+ EOR
39
+ view = Couchbase::View.new(stub(:curl_easy => response),
40
+ "http://localhost:5984/default/_design/test/_view/all")
41
+ assert_raises(Couchbase::ViewError) do
42
+ view.fetch
43
+ end
44
+ end
45
+
46
+ def test_when_stream_has_errors_and_error_callback_provided_it_executes_the_callback
47
+ response = <<-EOR
48
+ {
49
+ "total_rows": 0,
50
+ "rows": [ ],
51
+ "errors": [
52
+ {
53
+ "from": "127.0.0.1:5984",
54
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_b`."
55
+ },
56
+ {
57
+ "from": "http:// localhost:5984/_view_merge/",
58
+ "reason": "Design document `_design/testfoobar` missing in database `test_db_c`."
59
+ }
60
+ ]
61
+ }
62
+ EOR
63
+ view = Couchbase::View.new(stub(:curl_easy => response),
64
+ "http://localhost:5984/default/_design/test/_view/all")
65
+ errcount = 0
66
+ view.on_error{|from, reason| errcount += 1}
67
+ view.fetch
68
+ assert 2, errcount
69
+ end
70
+
71
+ protected
72
+
73
+ def populate_database
74
+ connection = Couchbase.new('http://localhost:8091/pools/default')
75
+ # clear storage
76
+ connection.flush
77
+ # save 100 documents
78
+ toys = %w(buzz rex bo hamm slink potato)
79
+ 100.times do |t|
80
+ connection["test_view_#{t}"]= {:counter => t+1, :toy => toys[t%6]}
81
+ end
82
+
83
+ connection.delete_design_doc('test_view')
84
+ connection.save_design_doc('_id' => '_design/test_view',
85
+ 'views' => {
86
+ 'all' => {'map' => 'function(doc){if(doc.counter){emit(doc._id, doc)}}'},
87
+ 'sum' => {'map' => 'function(doc){if(doc.counter){emit(doc.toy, doc.counter)}}',
88
+ 'reduce' => 'function(keys,values,rereduce){return sum(values)}'}})
89
+
90
+ assert connection.design_docs['test_view']
91
+
92
+ assert_operation_completed do
93
+ database_ready(connection) && connection.all_docs.count > 100
94
+ end
95
+ connection
96
+ end
97
+
98
+ end
metadata ADDED
@@ -0,0 +1,164 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couchbase
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Couchbase
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-05 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: memcached
16
+ requirement: &21810440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *21810440
25
+ - !ruby/object:Gem::Dependency
26
+ name: yajl-ruby
27
+ requirement: &21809260 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.8.2
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *21809260
36
+ - !ruby/object:Gem::Dependency
37
+ name: curb
38
+ requirement: &21808520 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.7.15
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *21808520
47
+ - !ruby/object:Gem::Dependency
48
+ name: yaji
49
+ requirement: &21807740 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.9
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *21807740
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &21807100 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *21807100
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: &21806400 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *21806400
80
+ - !ruby/object:Gem::Dependency
81
+ name: mocha
82
+ requirement: &21805980 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *21805980
91
+ description: The official client library for use with Couchbase Server.
92
+ email: info@couchbase.com
93
+ executables: []
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - .gitignore
98
+ - Gemfile
99
+ - HISTORY.markdown
100
+ - LICENSE
101
+ - README.markdown
102
+ - Rakefile
103
+ - couchbase.gemspec
104
+ - lib/couchbase.rb
105
+ - lib/couchbase/bucket.rb
106
+ - lib/couchbase/couchdb.rb
107
+ - lib/couchbase/document.rb
108
+ - lib/couchbase/http_status.rb
109
+ - lib/couchbase/latch.rb
110
+ - lib/couchbase/memcached.rb
111
+ - lib/couchbase/node.rb
112
+ - lib/couchbase/rest_client.rb
113
+ - lib/couchbase/version.rb
114
+ - lib/couchbase/view.rb
115
+ - test/setup.rb
116
+ - test/support/buckets-config.json
117
+ - test/support/sample_design_doc.json
118
+ - test/test_bucket.rb
119
+ - test/test_couchbase.rb
120
+ - test/test_couchdb.rb
121
+ - test/test_document.rb
122
+ - test/test_latch.rb
123
+ - test/test_memcached.rb
124
+ - test/test_rest_client.rb
125
+ - test/test_version.rb
126
+ - test/test_view.rb
127
+ homepage: http://couchbase.org
128
+ licenses:
129
+ - ASL-2
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 1.8.10
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: Couchbase ruby driver
152
+ test_files:
153
+ - test/setup.rb
154
+ - test/support/buckets-config.json
155
+ - test/support/sample_design_doc.json
156
+ - test/test_bucket.rb
157
+ - test/test_couchbase.rb
158
+ - test/test_couchdb.rb
159
+ - test/test_document.rb
160
+ - test/test_latch.rb
161
+ - test/test_memcached.rb
162
+ - test/test_rest_client.rb
163
+ - test/test_version.rb
164
+ - test/test_view.rb