activecouch 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README +42 -0
  3. data/Rakefile +31 -0
  4. data/VERSION +1 -0
  5. data/lib/active_couch.rb +18 -0
  6. data/lib/active_couch/associations.rb +1 -0
  7. data/lib/active_couch/associations/has_many_association.rb +35 -0
  8. data/lib/active_couch/attribute.rb +46 -0
  9. data/lib/active_couch/base.rb +458 -0
  10. data/lib/active_couch/callbacks.rb +81 -0
  11. data/lib/active_couch/connection.rb +155 -0
  12. data/lib/active_couch/errors.rb +17 -0
  13. data/lib/active_couch/migrations.rb +3 -0
  14. data/lib/active_couch/migrations/errors.rb +4 -0
  15. data/lib/active_couch/migrations/migration.rb +77 -0
  16. data/lib/active_couch/migrations/migrator.rb +53 -0
  17. data/lib/active_couch/support.rb +2 -0
  18. data/lib/active_couch/support/extensions.rb +92 -0
  19. data/lib/active_couch/support/inflections.rb +52 -0
  20. data/lib/active_couch/support/inflector.rb +280 -0
  21. data/spec/attribute/initialize_spec.rb +138 -0
  22. data/spec/base/after_delete_spec.rb +107 -0
  23. data/spec/base/after_save_spec.rb +99 -0
  24. data/spec/base/before_delete_spec.rb +106 -0
  25. data/spec/base/before_save_spec.rb +98 -0
  26. data/spec/base/create_spec.rb +27 -0
  27. data/spec/base/database_spec.rb +65 -0
  28. data/spec/base/delete_spec.rb +78 -0
  29. data/spec/base/find_spec.rb +165 -0
  30. data/spec/base/from_json_spec.rb +48 -0
  31. data/spec/base/has_many_spec.rb +81 -0
  32. data/spec/base/has_spec.rb +76 -0
  33. data/spec/base/id_spec.rb +22 -0
  34. data/spec/base/initialize_spec.rb +43 -0
  35. data/spec/base/module_spec.rb +18 -0
  36. data/spec/base/nested_class_spec.rb +19 -0
  37. data/spec/base/rev_spec.rb +16 -0
  38. data/spec/base/save_spec.rb +65 -0
  39. data/spec/base/site_spec.rb +41 -0
  40. data/spec/base/to_json_spec.rb +64 -0
  41. data/spec/connection/initialize_spec.rb +28 -0
  42. data/spec/has_many_association/initialize_spec.rb +33 -0
  43. data/spec/migration/define_spec.rb +29 -0
  44. data/spec/migration/include_attributes_spec.rb +30 -0
  45. data/spec/migration/view_js_spec.rb +46 -0
  46. data/spec/migration/with_filter_spec.rb +13 -0
  47. data/spec/migration/with_key_spec.rb +13 -0
  48. data/spec/migrator/create_database_spec.rb +48 -0
  49. data/spec/migrator/delete_database_spec.rb +46 -0
  50. data/spec/migrator/migrate_spec.rb +99 -0
  51. data/spec/spec_helper.rb +9 -0
  52. metadata +104 -0
@@ -0,0 +1,22 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "An object instantiated from the subclass of ActiveCouch::Base" do
4
+ before(:each) do
5
+ class Person < ActiveCouch::Base
6
+ has :name, :which_is => :text
7
+ end
8
+
9
+ @person = Person.new
10
+ end
11
+
12
+ it "should have accessors for the id attribute" do
13
+ @person.should respond_to(:id)
14
+ @person.should respond_to(:id=)
15
+ end
16
+
17
+ it "should be able to set and retrieve the id variable" do
18
+ @person.id = 'abc-def'
19
+ @person.id.should == 'abc-def'
20
+ end
21
+
22
+ end
@@ -0,0 +1,43 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "ActiveCouch::Base #new method with a hash containing one key-value pair" do
4
+ before(:each) do
5
+ class Person < ActiveCouch::Base
6
+ has :name
7
+ end
8
+ end
9
+
10
+ it "should be able to initialize attributes correctly from a hash" do
11
+ p = Person.new(:name => 'McLovin')
12
+ p.name.should == 'McLovin'
13
+ end
14
+ end
15
+
16
+ describe "ActiveCouch::Base #new method with a hash containing more than one key-value pair" do
17
+ before(:each) do
18
+ class Person < ActiveCouch::Base
19
+ has :name
20
+ has :age, :which_is => :number, :with_default_value => 25
21
+ end
22
+ end
23
+
24
+ it "should be able to initialize attributes correctly from the hash" do
25
+ p = Person.new(:name => 'McLovin', :age => 12)
26
+ p.name.should == 'McLovin'
27
+ p.age.should == 12
28
+ end
29
+ end
30
+
31
+ describe "ActiveCouch::Base #new method with a hash containing a CouchDB reserved attribute" do
32
+ before(:each) do
33
+ class Person < ActiveCouch::Base
34
+ has :name
35
+ end
36
+ end
37
+
38
+ it "should be able to initialize attributes correclty from the has, including CouchDB reserved attributes" do
39
+ p = Person.new(:name => 'McLovin', :id => '123')
40
+ p.name.should == 'McLovin'
41
+ p.id.should == '123'
42
+ end
43
+ end
@@ -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,16 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "An object instantiated from the subclass of ActiveCouch::Base" do
4
+ before(:each) do
5
+ class Person < ActiveCouch::Base
6
+ has :name, :which_is => :text
7
+ end
8
+
9
+ @person = Person.new
10
+ end
11
+
12
+ it "should have reader/writer for the rev attribute" do
13
+ @person.should respond_to(:rev)
14
+ @person.should respond_to(:rev=)
15
+ end
16
+ end
@@ -0,0 +1,65 @@
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::Migrator.create_database('http://localhost:5984/', 'people')
11
+ end
12
+
13
+ after(:each) do
14
+ # Delete after we're done
15
+ ActiveCouch::Migrator.delete_database('http://localhost:5984/', 'people')
16
+ end
17
+
18
+ it "should have an instance method called save" do
19
+ Person.new.methods.include?('save').should == true
20
+ end
21
+
22
+ it "should be able to persist itself in the CouchDB database" do
23
+ person = Person.new(:name => 'McLovin')
24
+ person.save.should == true
25
+ end
26
+ end
27
+
28
+ describe "A new ActiveCouch::Base instance" do
29
+ before(:each) do
30
+ class Person < ActiveCouch::Base
31
+ site 'http://localhost:5984/'
32
+ has :name, :which_is => :text
33
+ end
34
+
35
+ @person = Person.new(:name => 'Seth')
36
+ # Create a database called people
37
+ ActiveCouch::Migrator.create_database('http://localhost:5984/', 'people')
38
+ end
39
+
40
+ after(:each) do
41
+ # Delete after we're done
42
+ ActiveCouch::Migrator.delete_database('http://localhost:5984/', 'people')
43
+ end
44
+
45
+ it "should be new" do
46
+ @person.should be_new
47
+ end
48
+
49
+ it "should set the id and rev attributes after being saved" do
50
+ @person.save
51
+
52
+ @person.id.should_not == nil
53
+ @person.rev.should_not == nil
54
+ @person.should_not be_new
55
+ end
56
+
57
+ it "should allow you to set the id attribute, and the id must be reflected in the object after saving" do
58
+ @person.id = 'abc_def'
59
+ puts @person.to_json
60
+
61
+ @person.save
62
+ @person.id.should == 'abc_def'
63
+ end
64
+
65
+ end
@@ -0,0 +1,41 @@
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(:each) do
5
+ class Cat < ActiveCouch::Base
6
+ site 'http://192.168.0.150:7777'
7
+ end
8
+ end
9
+
10
+ after(:each) 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(:each) do
24
+ class Cat < ActiveCouch::Base
25
+ site 'http://192.168.0.150'
26
+ end
27
+ @cat = Cat.new
28
+ end
29
+
30
+ after(:each) 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
@@ -0,0 +1,64 @@
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
+ it "should have to the to_json method" do
15
+ @h.should respond_to(:to_json)
16
+ end
17
+
18
+ it "should produce valid JSON output when sent the to_json method" do
19
+ json_output = @h.to_json
20
+ # Check for JSON regex, since attributes can appear in any order
21
+ (json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
22
+ (json_output =~ /"rooms":100/).should_not == nil
23
+ (json_output =~ /"star_rating":5.0/).should_not == nil
24
+ end
25
+
26
+ it "should produce valid JSON output when an attribute has been changed and the to_json method is sent" do
27
+ @h.rooms = 200
28
+ json_output = @h.to_json
29
+ # Check for JSON regex, since attributes can appear in any order
30
+ (json_output =~ /"name":"Swissotel The Stamford"/).should_not == nil
31
+ (json_output =~ /"rooms":200/).should_not == nil
32
+ (json_output =~ /"star_rating":5.0/).should_not == nil
33
+ end
34
+ end
35
+
36
+ describe "ActiveCouch::Base #to_json with associations" do
37
+ before(:each) do
38
+ class Hospital < ActiveCouch::Base
39
+ has :name
40
+ end
41
+
42
+ class CrazyPerson < ActiveCouch::Base
43
+ has :name, :which_is => :text, :with_default_value => "Crazed McLovin"
44
+ has_many :hospitals
45
+ end
46
+
47
+ @c = CrazyPerson.new
48
+
49
+ @h1 = Hospital.new(:name => "Crazy Hospital 1")
50
+ @h2 = Hospital.new(:name => "Crazy Hospital 2")
51
+
52
+ @c.add_hospital(@h1)
53
+ @c.add_hospital(@h2)
54
+ end
55
+
56
+ it "should produce valid JSON when sent the to_json method" do
57
+ json_output = @c.to_json
58
+ # Check for JSON regex, since attributes can appear in any order
59
+ (json_output =~ /"name":"Crazed McLovin"/).should_not == nil
60
+ (json_output =~ /"hospitals":\[.*?\]/).should_not == nil
61
+ (json_output =~ /\{.*?"name":"Crazy Hospital 1".*?\}/).should_not == nil
62
+ (json_output =~ /\{.*?"name":"Crazy Hospital 2".*?\}/).should_not == nil
63
+ end
64
+ 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,33 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ class EmptyPerson < ActiveCouch::Base; end
4
+
5
+ describe "An ActiveCouch::HasManyAssociation object initialized with a name and with class set to Person" do
6
+ before(:each) do
7
+ @a = ActiveCouch::HasManyAssociation.new(:contacts, :class => EmptyPerson)
8
+ end
9
+
10
+ it "should set the klass to Person name must be contacts" do
11
+ @a.klass.should == EmptyPerson
12
+ @a.name.should == "contacts"
13
+ @a.container.should == []
14
+ end
15
+ end
16
+
17
+ describe "An ActiveCouch::HasManyAssociation object initialized with only a name" do
18
+ before(:each) do
19
+ @a = ActiveCouch::HasManyAssociation.new(:empty_people)
20
+ end
21
+
22
+ it "should set the klass to Person name must be people" do
23
+ @a.klass.should == EmptyPerson
24
+ @a.name.should == "empty_people"
25
+ @a.container.should == []
26
+ end
27
+ end
28
+
29
+ describe "An ActiveCouch::HasManyAssociation object initialized with only a name (but for which a class is not defined)" do
30
+ it "should raise a NameError" do
31
+ lambda { ass.new(:contacts) }.should raise_error(NameError)
32
+ end
33
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "ActiveCouch::Migration #define method" do
4
+ it "should set @view and @database correctly if the first param is a String/Symbol" do
5
+ class ByName < ActiveCouch::Migration
6
+ define :by_name, :for_db => 'people'
7
+ end
8
+
9
+ ByName.instance_variable_get("@view").should == 'by_name'
10
+ ByName.instance_variable_get("@database").should == 'people'
11
+ end
12
+
13
+ it "should set @view correctly if the first param passed is not a String/Symbol" do
14
+ class ByFace < ActiveCouch::Migration
15
+ define :for_db => 'people'
16
+ end
17
+
18
+ ByFace.instance_variable_get("@view").should == 'by_face'
19
+ ByFace.instance_variable_get("@database").should == 'people'
20
+ end
21
+
22
+ it "should raise an exception if neither the view nor the database is given as parameters" do
23
+ lambda {
24
+ class Test < ActiveCouch::Migration; define; end
25
+ }.should raise_error(ArgumentError, 'Wrong arguments used to define the view')
26
+ end
27
+ end
28
+
29
+
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "ActiveCouch::Migration #include_attributes method" do
4
+ it "should set the attrs instance variable to an array, if passed a multi-element array" do
5
+ class ByLongitude < ActiveCouch::Migration
6
+ define :for_db => 'hotels' do
7
+ include_attributes :name, :rating, :latitude, :longitude, :address
8
+ end
9
+ end
10
+ ByLongitude.instance_variable_get("@attrs").should == [:name, :rating, :latitude, :longitude, :address]
11
+ end
12
+
13
+ it "should set the attrs instance variable correctly, if passed a single-element array" do
14
+ class ByLongitude < ActiveCouch::Migration
15
+ define :for_db => 'hotels' do
16
+ include_attributes :name
17
+ end
18
+ end
19
+ ByLongitude.instance_variable_get("@attrs").should == [:name]
20
+ end
21
+
22
+ it "should set the attrs instance variable to an empty array, if not passed an array" do
23
+ class ByLongitude < ActiveCouch::Migration
24
+ define :for_db => 'hotels' do
25
+ include_attributes {}
26
+ end
27
+ end
28
+ ByLongitude.instance_variable_get("@attrs").should == []
29
+ end
30
+ end
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper.rb'
2
+
3
+ describe "ActiveCouch::Migration #view_js method" do
4
+ before(:each) do
5
+ class ByName < ActiveCouch::Migration
6
+ define :by_name, :for_db => 'people' do
7
+ with_key 'name'
8
+ end
9
+ end
10
+ end
11
+
12
+ it "should generate the correct javascript to be used in the view" do
13
+ (ByName.view_js =~ /map\(doc\.name, doc\);/).should_not == nil
14
+ end
15
+ end
16
+
17
+ describe "ActiveCouch::Migration #view_js method while calling the with_key and with_filter methods" do
18
+ before(:each) do
19
+ class ByLatitude < ActiveCouch::Migration
20
+ define :for_db => 'hotels' do
21
+ with_key 'latitude'
22
+ with_filter 'doc.name == "Hilton"'
23
+ end
24
+ end
25
+ end
26
+
27
+ it "should generate the correct javascript to be used in the view" do
28
+ (ByLatitude.view_js =~ /map\(doc\.latitude, doc\);/).should_not == nil
29
+ (ByLatitude.view_js =~ /if\(doc\.name == \\"Hilton\\"\)/).should_not == nil
30
+ end
31
+ end
32
+
33
+ describe "A subclass of ActiveCouch::Migration while calling with_key and include_attributes method" do
34
+ before(:each) do
35
+ class ByLongitude < ActiveCouch::Migration
36
+ define :for_db => 'hotels' do
37
+ with_key 'latitude'
38
+ include_attributes :name, :rating, :latitude, :longitude, :address
39
+ end
40
+ end
41
+ end
42
+
43
+ it "should generate the correct javascript which will be used in the permanent view" do
44
+ (ByLongitude.view_js =~ /map\(doc\.latitude, \{name: doc\.name , rating: doc\.rating , latitude: doc\.latitude , longitude: doc\.longitude , address: doc\.address\}\);/).should_not == nil
45
+ end
46
+ end