peleteiro-activecouch 0.2.1

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.
Files changed (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +28 -0
  3. data/Rakefile +52 -0
  4. data/VERSION +1 -0
  5. data/lib/active_couch.rb +12 -0
  6. data/lib/active_couch/base.rb +608 -0
  7. data/lib/active_couch/callbacks.rb +89 -0
  8. data/lib/active_couch/connection.rb +164 -0
  9. data/lib/active_couch/errors.rb +13 -0
  10. data/lib/active_couch/support.rb +3 -0
  11. data/lib/active_couch/support/exporter.rb +97 -0
  12. data/lib/active_couch/support/extensions.rb +86 -0
  13. data/lib/active_couch/support/inflections.rb +52 -0
  14. data/lib/active_couch/support/inflector.rb +279 -0
  15. data/lib/active_couch/views.rb +3 -0
  16. data/lib/active_couch/views/errors.rb +4 -0
  17. data/lib/active_couch/views/raw_view.rb +40 -0
  18. data/lib/active_couch/views/view.rb +85 -0
  19. data/lib/activecouch.rb +1 -0
  20. data/spec/base/after_delete_spec.rb +110 -0
  21. data/spec/base/after_save_spec.rb +102 -0
  22. data/spec/base/before_delete_spec.rb +109 -0
  23. data/spec/base/before_save_spec.rb +101 -0
  24. data/spec/base/count_all_spec.rb +29 -0
  25. data/spec/base/count_spec.rb +77 -0
  26. data/spec/base/create_spec.rb +28 -0
  27. data/spec/base/database_spec.rb +70 -0
  28. data/spec/base/delete_spec.rb +97 -0
  29. data/spec/base/find_from_url_spec.rb +55 -0
  30. data/spec/base/find_spec.rb +383 -0
  31. data/spec/base/from_json_spec.rb +54 -0
  32. data/spec/base/has_many_spec.rb +89 -0
  33. data/spec/base/has_spec.rb +88 -0
  34. data/spec/base/id_spec.rb +25 -0
  35. data/spec/base/initialize_spec.rb +91 -0
  36. data/spec/base/marshal_dump_spec.rb +64 -0
  37. data/spec/base/marshal_load_spec.rb +58 -0
  38. data/spec/base/module_spec.rb +18 -0
  39. data/spec/base/nested_class_spec.rb +19 -0
  40. data/spec/base/rev_spec.rb +20 -0
  41. data/spec/base/save_spec.rb +130 -0
  42. data/spec/base/site_spec.rb +62 -0
  43. data/spec/base/to_json_spec.rb +73 -0
  44. data/spec/connection/initialize_spec.rb +28 -0
  45. data/spec/exporter/all_databases_spec.rb +24 -0
  46. data/spec/exporter/create_database_spec.rb +47 -0
  47. data/spec/exporter/delete_database_spec.rb +45 -0
  48. data/spec/exporter/delete_spec.rb +36 -0
  49. data/spec/exporter/export_spec.rb +62 -0
  50. data/spec/exporter/export_with_raw_views_spec.rb +66 -0
  51. data/spec/spec_helper.rb +9 -0
  52. data/spec/views/define_spec.rb +34 -0
  53. data/spec/views/include_attributes_spec.rb +30 -0
  54. data/spec/views/raw_view_spec.rb +49 -0
  55. data/spec/views/to_json_spec.rb +58 -0
  56. data/spec/views/with_filter_spec.rb +13 -0
  57. data/spec/views/with_key_spec.rb +19 -0
  58. metadata +117 -0
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "A Cheezburger subclass of ActiveCouch::Base defined in the Burgers module" do
4
+ before(:all) do
5
+ module Burgers
6
+ class Cheezburger < ActiveCouch::Base
7
+ end
8
+ end
9
+ end
10
+
11
+ it "should have a base_class of Burgers::Cheezburger" do
12
+ Burgers::Cheezburger.base_class.should == Burgers::Cheezburger
13
+ end
14
+
15
+ it "should have a database_name of cheezburgers" do
16
+ Burgers::Cheezburger.database_name.should == 'cheezburgers'
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "A Cheezburger subclass of ActiveCouch::Base nested in a Lolcat subclass of ActiveCouch::Base" do
4
+ before(:all) do
5
+ class Lolcat < ActiveCouch::Base
6
+ class Cheezburger < ActiveCouch::Base
7
+ end
8
+ end
9
+ end
10
+
11
+ it "should have a base_class of Lolcat::Cheezburger" do
12
+ Lolcat.base_class.should == Lolcat
13
+ Lolcat::Cheezburger.base_class.should == Lolcat::Cheezburger
14
+ end
15
+
16
+ it "should have a database_name of lolcat_cheezburger" do
17
+ Lolcat::Cheezburger.database_name.should == 'lolcat_cheezburgers'
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "An object instantiated from the subclass of ActiveCouch::Base" do
4
+ before(:all) do
5
+ class Person < ActiveCouch::Base
6
+ has :name, :which_is => :text
7
+ end
8
+
9
+ @person = Person.new
10
+ end
11
+
12
+ after(:all) do
13
+ Object.send(:remove_const, :Person)
14
+ end
15
+
16
+ it "should have reader/writer for the rev attribute" do
17
+ @person.should respond_to(:rev)
18
+ @person.should respond_to(:rev=)
19
+ end
20
+ end
@@ -0,0 +1,130 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "A Person subclass of ActiveCouch::Base" do
4
+ before(:each) do
5
+ class Person < ActiveCouch::Base
6
+ site 'http://localhost:5984/'
7
+ has :name
8
+ end
9
+ # Create a database called people
10
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'people')
11
+ end
12
+
13
+ after(:each) do
14
+ # Delete after we're done
15
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'people')
16
+ Object.send(:remove_const, :Person)
17
+ end
18
+
19
+ it "should have an instance method called save" do
20
+ Person.new.methods.include?('save').should == true
21
+ end
22
+
23
+ it "should be able to persist itself in the CouchDB database" do
24
+ person = Person.new(:name => 'McLovin')
25
+ person.save.should == true
26
+ end
27
+ end
28
+
29
+ describe "A new ActiveCouch::Base instance" do
30
+ before(:each) do
31
+ class Person < ActiveCouch::Base
32
+ site 'http://localhost:5984/'
33
+ has :name, :which_is => :text
34
+ end
35
+
36
+ @person = Person.new(:name => 'Seth')
37
+ # Create a database called people
38
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'people')
39
+ end
40
+
41
+ after(:each) do
42
+ # Delete after we're done
43
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'people')
44
+ Object.send(:remove_const, :Person)
45
+ end
46
+
47
+ it "should be new" do
48
+ @person.should be_new
49
+ end
50
+
51
+ it "should set the id and rev attributes after being saved" do
52
+ @person.save
53
+
54
+ @person.id.should_not == nil
55
+ @person.rev.should_not == nil
56
+ @person.should_not be_new
57
+ end
58
+
59
+ it "should allow you to set the id attribute, and the id must be reflected in the object after saving" do
60
+ @person.id = 'abc_def'
61
+ @person.save
62
+
63
+ @person.id.should == 'abc_def'
64
+ end
65
+
66
+ it "should be allowed to save to a database with a name which does not correspond to the name of the class" do
67
+
68
+ end
69
+
70
+ end
71
+
72
+ describe "A new ActiveCouch::Base instance" do
73
+ before(:each) do
74
+ class Person < ActiveCouch::Base
75
+ site 'http://localhost:5984/'
76
+ has :name, :which_is => :text
77
+ end
78
+
79
+ @person = Person.new(:name => 'Seth')
80
+ # Create a database called people
81
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'good_people')
82
+ end
83
+
84
+ after(:each) do
85
+ # Delete after we're done
86
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'good_people')
87
+ Object.send(:remove_const, :Person)
88
+ end
89
+
90
+ it "should be new" do
91
+ @person.should be_new
92
+ end
93
+
94
+ it "should be allowed to save to a database with a name which does not correspond to the name of the class" do
95
+ @person.save(:to_database => 'good_people')
96
+
97
+ @person.id.should_not == nil
98
+ @person.rev.should_not == nil
99
+ @person.should_not be_new
100
+ end
101
+
102
+ end
103
+
104
+ describe "A new ActiveCouch::Base instance" do
105
+ before(:each) do
106
+ class Person < ActiveCouch::Base
107
+ site 'http://localhost:5984/'
108
+ has :name, :which_is => :text
109
+ end
110
+
111
+ @person = Person.new(:name => 'Seth')
112
+ # Create a database called people
113
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'people')
114
+ # Save the document
115
+ @person.save
116
+ end
117
+
118
+ after(:each) do
119
+ # Delete after we're done
120
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'people')
121
+ Object.send(:remove_const, :Person)
122
+ end
123
+
124
+ it "should be allowed to update a field and save again" do
125
+ @person.name = "McLovin"
126
+ @person.save.should == true
127
+
128
+ @person.name.should == "McLovin"
129
+ end
130
+ end
@@ -0,0 +1,62 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "A subclass of ActiveCouch::Base object which has called establish_connection" do
4
+ before(:all) do
5
+ class Cat < ActiveCouch::Base
6
+ site 'http://192.168.0.150:7777'
7
+ end
8
+ end
9
+
10
+ after(:all) do
11
+ # Remove class definition so we can start fresh in each spec.
12
+ Object.send(:remove_const, :Cat)
13
+ end
14
+
15
+ it "should have the method connection" do
16
+ Cat.methods.index('connection').should_not == nil
17
+ Cat.connection.site.host.should == '192.168.0.150'
18
+ Cat.connection.site.port.should == 7777
19
+ end
20
+ end
21
+
22
+ describe "An object instantiated from a subclass of ActiveCouch::Base which has called establish_connection" do
23
+ before(:all) do
24
+ class Cat < ActiveCouch::Base
25
+ site 'http://192.168.0.150'
26
+ end
27
+ @cat = Cat.new
28
+ end
29
+
30
+ after(:all) do
31
+ # Remove class definition so we can start fresh in each spec.
32
+ Object.send(:remove_const, :Cat)
33
+ end
34
+
35
+
36
+ it "should have the method connection in objects instantiated from the subclass" do
37
+ @cat.methods.index('connection').should_not == nil
38
+ @cat.connection.site.host.should == '192.168.0.150'
39
+ @cat.connection.site.port.should == 5984
40
+ end
41
+ end
42
+
43
+
44
+ describe "If the site is set in ActiveCouch::Base, all instances and all subclasses of ActiveCouch::Base should inherit it" do
45
+ before(:all) do
46
+ ActiveCouch::Base.send('site', 'http://localhost.site:5984')
47
+ class P < ActiveCouch::Base; end
48
+ @p = P.new
49
+ end
50
+
51
+ after(:all) do
52
+ Object.send(:remove_const, :P)
53
+ end
54
+
55
+ it "should be reflected in @p and P" do
56
+ P.instance_variable_get('@connection').should_not == nil
57
+ @p.methods.index('connection').should_not == nil
58
+ @p.connection.site.host.should == 'localhost.site'
59
+ @p.connection.site.port.should == 5984
60
+ end
61
+ end
62
+
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "ActiveCouch::Base #to_json method with just simple attributes" do
4
+ before(:each) do
5
+ class Hotel < ActiveCouch::Base
6
+ has :name, :which_is => :text, :with_default_value => "Swissotel The Stamford"
7
+ has :star_rating, :which_is => :decimal, :with_default_value => 5.0
8
+ has :rooms, :which_is => :number, :with_default_value => 100
9
+ end
10
+
11
+ @h = Hotel.new
12
+ end
13
+
14
+ after(:each) do
15
+ Object.send(:remove_const, :Hotel)
16
+ end
17
+
18
+ it "should have to the to_json method" do
19
+ @h.should respond_to(:to_json)
20
+ end
21
+
22
+ it "should produce valid JSON output when sent the to_json method" do
23
+ json_output = @h.to_json
24
+ # Check for JSON regex, since attributes can appear in any order
25
+ (json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
26
+ (json_output =~ /"rooms":100/).should_not == nil
27
+ (json_output =~ /"star_rating":5.0/).should_not == nil
28
+ end
29
+
30
+ it "should produce valid JSON output when an attribute has been changed and the to_json method is sent" do
31
+ @h.rooms = 200
32
+ json_output = @h.to_json
33
+ # Check for JSON regex, since attributes can appear in any order
34
+ (json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
35
+ (json_output =~ /"rooms":200/).should_not == nil
36
+ (json_output =~ /"star_rating":5.0/).should_not == nil
37
+ end
38
+ end
39
+
40
+ describe "ActiveCouch::Base #to_json with associations" do
41
+ before(:each) do
42
+ class Hospital < ActiveCouch::Base
43
+ has :name
44
+ end
45
+
46
+ class CrazyPerson < ActiveCouch::Base
47
+ has :name, :which_is => :text, :with_default_value => "Crazed McLovin"
48
+ has_many :hospitals
49
+ end
50
+
51
+ @c = CrazyPerson.new
52
+
53
+ @h1 = Hospital.new(:name => "Crazy Hospital 1")
54
+ @h2 = Hospital.new(:name => "Crazy Hospital 2")
55
+
56
+ @c.add_hospital(@h1)
57
+ @c.add_hospital(@h2)
58
+ end
59
+
60
+ after(:each) do
61
+ Object.send(:remove_const, :Hospital)
62
+ Object.send(:remove_const, :CrazyPerson)
63
+ end
64
+
65
+ it "should produce valid JSON when sent the to_json method" do
66
+ json_output = @c.to_json
67
+ # Check for JSON regex, since attributes can appear in any order
68
+ (json_output =~ /"name":"Crazed McLovin"/).should_not == nil
69
+ (json_output =~ /"hospitals":\[.*?\]/).should_not == nil
70
+ (json_output =~ /\{.*?"name":"Crazy Hospital 1".*?\}/).should_not == nil
71
+ (json_output =~ /\{.*?"name":"Crazy Hospital 2".*?\}/).should_not == nil
72
+ end
73
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe ActiveCouch::Connection do
4
+ it "should set the site for the connection object and there must be no error" do
5
+ @connection = ActiveCouch::Connection.new('http://192.168.0.150:7777')
6
+
7
+ @connection.site.host.should == "192.168.0.150"
8
+ @connection.site.port.should == 7777
9
+ @error.should == nil
10
+ end
11
+ end
12
+
13
+ describe "An ActiveCouch::Connection object instantiated with no site specified" do
14
+ it "should raise an ArgumentError and return nil" do
15
+ lambda {
16
+ @connection = ActiveCouch::Connection.new(nil)
17
+ }.should raise_error(ArgumentError, 'Missing site URI')
18
+ end
19
+ end
20
+
21
+ describe "An ActiveCouch::Connection object instantiated with site (with no port) specified" do
22
+ it "should use the default CouchDB port of 5984" do
23
+ @connection = ActiveCouch::Connection.new('http://192.168.0.150')
24
+
25
+ @connection.site.host.should == "192.168.0.150"
26
+ @connection.site.port.should == 5984
27
+ end
28
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ describe ActiveCouch::Exporter, "#all_databases (that actually connects to a CouchDB server)" do
7
+ before(:each) do
8
+ @original_db_size = ActiveCouch::Exporter.all_databases('http://localhost:5984').size
9
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'ac_test_1')
10
+ ActiveCouch::Exporter.create_database('http://localhost:5984/', 'ac_test_2')
11
+ end
12
+
13
+ after(:each) do
14
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'ac_test_1')
15
+ ActiveCouch::Exporter.delete_database('http://localhost:5984/', 'ac_test_2')
16
+ end
17
+
18
+ it "should list all databases currently in CouchDB" do
19
+ databases = ActiveCouch::Exporter.all_databases('http://localhost:5984')
20
+ databases.size.should == (2 + @original_db_size)
21
+ databases.include?('ac_test_1').should == true
22
+ databases.include?('ac_test_2').should == true
23
+ end
24
+ end
@@ -0,0 +1,47 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe ActiveCouch::Exporter, "#create_database with site and name" do
4
+ before(:each) do
5
+ @conn = mock(ActiveCouch::Connection)
6
+ @response = mock(Object, :code => '201')
7
+ end
8
+
9
+ def mock_connection_and_response(options = {})
10
+ ActiveCouch::Connection.should_receive(:new).with(options[:site]).and_return(@conn)
11
+ @conn.should_receive(:put).with("/#{options[:database_name]}", '{}').and_return(@response)
12
+ end
13
+
14
+ it "should create a new Connection to the given site and send a PUT with the database name" do
15
+ # Mock and place expectations on the the connection and response out explicitly instead of using
16
+ # mock_connection_and_response so that it's clearer what we're testing in this spec.
17
+ ActiveCouch::Connection.should_receive(:new).with('http://test.host:5984/').and_return(@conn)
18
+ @conn.should_receive(:put).with('/test', '{}').and_return(@response)
19
+
20
+ ActiveCouch::Exporter.create_database('http://test.host:5984/', 'test')
21
+ end
22
+
23
+ it "should return true if the response code is HTTP status 201" do
24
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'test')
25
+ @response.should_receive(:code).and_return('201')
26
+
27
+ ActiveCouch::Exporter.create_database('http://test.host:5984/', 'test').should == true
28
+ end
29
+
30
+ it "should raise an ActiveCouch::ViewError if the response code is not HTTP status 201" do
31
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'test')
32
+ @response.should_receive(:code).any_number_of_times.and_return('500')
33
+
34
+ lambda {
35
+ ActiveCouch::Exporter.create_database('http://test.host:5984/', 'test')
36
+ }.should raise_error(ActiveCouch::ViewError)
37
+ end
38
+
39
+ it "should raise an ActiveCouch::ViewError with a 'Database exists' message if the response code is HTTP status 409" do
40
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'test')
41
+ @response.should_receive(:code).any_number_of_times.and_return('409')
42
+
43
+ lambda {
44
+ ActiveCouch::Exporter.create_database('http://test.host:5984/', 'test')
45
+ }.should raise_error(ActiveCouch::ViewError, 'Database exists')
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe ActiveCouch::Exporter, "#delete_database with site and name" do
4
+ before(:each) do
5
+ @conn = mock(ActiveCouch::Connection)
6
+ @response = mock(Object, :code => '202')
7
+ end
8
+
9
+ def mock_connection_and_response(options = {})
10
+ ActiveCouch::Connection.should_receive(:new).with(options[:site]).and_return(@conn)
11
+ @conn.should_receive(:delete).with("/#{options[:database_name]}").and_return(@response)
12
+ end
13
+
14
+ it "should create a new Connection to the given site and send a DELETE with the database name" do
15
+ ActiveCouch::Connection.should_receive(:new).with('http://test.host:5984/').and_return(@conn)
16
+ @conn.should_receive(:delete).with('/delete_me').and_return(@response)
17
+
18
+ ActiveCouch::Exporter.delete_database('http://test.host:5984/', 'delete_me')
19
+ end
20
+
21
+ it "should return true if the response code is HTTP status 202" do
22
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'delete_me')
23
+ @response.should_receive(:code).and_return('202')
24
+
25
+ ActiveCouch::Exporter.delete_database('http://test.host:5984/', 'delete_me').should == true
26
+ end
27
+
28
+ it "should raise an ActiveCouch::ViewError if the response code is not HTTP status 202" do
29
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'delete_me')
30
+ @response.should_receive(:code).any_number_of_times.and_return('500')
31
+
32
+ lambda {
33
+ ActiveCouch::Exporter.delete_database('http://test.host:5984/', 'delete_me')
34
+ }.should raise_error(ActiveCouch::ViewError)
35
+ end
36
+
37
+ it "should raise an ActiveCouch::ViewError with a 'Database does not exist' message if the response code is HTTP status 404" do
38
+ mock_connection_and_response(:site => 'http://test.host:5984/', :database_name => 'delete_me')
39
+ @response.should_receive(:code).any_number_of_times.and_return('404')
40
+
41
+ lambda {
42
+ ActiveCouch::Exporter.delete_database('http://test.host:5984/', 'delete_me')
43
+ }.should raise_error(ActiveCouch::ViewError, "Database 'delete_me' does not exist")
44
+ end
45
+ end