correlate 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,49 @@
1
+ module Correlate
2
+ class Validator < ::CouchRest::Validation::GenericValidator
3
+
4
+ def initialize( field_name, options = {} )
5
+ super
6
+ @field_name, @options = field_name, options
7
+ end
8
+
9
+ def call( target )
10
+ results = []
11
+
12
+ target.class.correlations.each do |correlation|
13
+ case correlation.type
14
+ when :some
15
+ results << validate_some( correlation, target )
16
+ when :a
17
+ results << validate_a( correlation, target )
18
+ end
19
+ end
20
+
21
+ !results.any? { |r| r == false }
22
+ end
23
+
24
+ def validate_some( correlation, target )
25
+ results = true
26
+
27
+ case correlation.requires
28
+ when Fixnum
29
+ unless target.send( correlation.name, true ).size >= correlation.requires
30
+ target.errors.add( correlation.name, "Requires at least #{correlation.requires} #{correlation.name}" )
31
+ results = false
32
+ end
33
+ end
34
+
35
+ results
36
+ end
37
+
38
+ def validate_a( correlation, target )
39
+ results = true
40
+
41
+ if correlation.required && target.send( correlation.name ).nil?
42
+ target.errors.add( correlation.name, "is required" )
43
+ results = false
44
+ end
45
+
46
+ results
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correlate, ActiveRecord do
4
+ fixtures :article, :comment
5
+
6
+ before(:each) do
7
+ @article = Article.create( :title => 'Correlations in C' )
8
+ end
9
+
10
+ it "should have an empty association" do
11
+ @article.comments.should be_empty
12
+ end
13
+
14
+ it "should accept a new associated document" do
15
+ comment = Comment.create( :comment => 'awesome' )
16
+ @article.comments << comment
17
+
18
+ @article.comments.should == [ comment ]
19
+ end
20
+
21
+ it "should be reciprocal" do
22
+ comment = Comment.create( :comment => 'extreme' )
23
+ comment.article = @article
24
+
25
+ comment.article.should == @article
26
+ comment.save
27
+
28
+ Comment.get( comment.id ).article.should == @article
29
+ end
30
+ end
@@ -0,0 +1,17 @@
1
+ require 'activerecord'
2
+
3
+ # Setup connection
4
+ def reset_test_sqlitedb!
5
+ ActiveRecord::Base.connection.disconnect! rescue nil
6
+ ActiveRecord::Base.establish_connection(
7
+ :adapter => 'sqlite3',
8
+ :database => ':memory:'
9
+ )
10
+
11
+ ActiveRecord::Schema.verbose = false
12
+ ActiveRecord::Schema.define do
13
+ create_table :articles do |t|
14
+ t.string 'title'
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,132 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Correlate do
4
+ fixtures :person, :reader, :news_feed, :crawler
5
+
6
+ describe "extends classes" do
7
+ it "to track correlations" do
8
+ Person.correlations.should_not be_empty
9
+
10
+ correlation = Person.correlations.first
11
+ correlation.should be_a_kind_of( Correlate::Correlation )
12
+ correlation.type.should == :some
13
+ correlation.name.should == :people
14
+ correlation.target.should == 'Person'
15
+ correlation.source.should == Person
16
+ end
17
+
18
+ it "should define a view for looking up rels" do
19
+ Person.should have_view('by_rel')
20
+ end
21
+ end
22
+
23
+ describe "to self" do
24
+ before(:each) do
25
+ @person = Person.new
26
+ end
27
+
28
+ it "should have an empty array" do
29
+ @person.people.should be_a_kind_of( Array )
30
+ @person.people.should be_empty
31
+ end
32
+
33
+ it "should accept new associations" do
34
+ person = Person.create :name => 'John'
35
+ @person.people << person
36
+
37
+ @person.links.should == [{ 'rel' => 'person', 'href' => person.id }]
38
+ @person.save!
39
+
40
+ Person.get( @person.id ).links.should == [{ 'rel' => 'person', 'href' => person.id }]
41
+ end
42
+
43
+ it "should load objects from associations" do
44
+ person = Person.create :name => 'Jack'
45
+ @person.people << person
46
+ @person.save!
47
+
48
+ @person.people.should == [ person ]
49
+ end
50
+
51
+ it "should have the raw associations" do
52
+ person = Person.create :name => 'Jack'
53
+ @person.people << person
54
+ @person.save!
55
+
56
+ @person.people( true ).should == [{'rel' => 'person', 'href' => person.id }]
57
+ end
58
+ end
59
+
60
+ describe "to some others" do
61
+ before(:each) do
62
+ @reader = Reader.new
63
+ end
64
+
65
+ it "should have an empty array" do
66
+ @reader.news_feeds.should be_empty
67
+ end
68
+
69
+ it "should accept new associations" do
70
+ feed = NewsFeed.create :url => 'http://planet.couchdb.com/atom.xml'
71
+ @reader.news_feeds << feed
72
+
73
+ @reader.links.should == [{ 'rel' => 'news_feed', 'href' => feed.id }]
74
+ @reader.save!
75
+
76
+ Reader.get( @reader.id ).links.should == [{ 'rel' => 'news_feed', 'href' => feed.id }]
77
+ end
78
+
79
+ it "should load objects from associations" do
80
+ feed = NewsFeed.create :url => 'http://planet.couchdb.com/atom.xml'
81
+ @reader.news_feeds << feed
82
+ @reader.save!
83
+
84
+ @reader.news_feeds.should == [ feed ]
85
+ end
86
+
87
+ it "should have access to the raw accosiations" do
88
+ feed = NewsFeed.create :url => 'http://planet.couchdb.com/atom.xml'
89
+ @reader.news_feeds << feed
90
+ @reader.save!
91
+
92
+ @reader.news_feeds( true ).should == [{ 'rel' => 'news_feed', 'href' => feed.id }]
93
+ end
94
+ end
95
+
96
+ describe "to another" do
97
+ before(:each) do
98
+ @feed = NewsFeed.new( :url => 'http://planet.couchdb.com/atom.xml' )
99
+ end
100
+
101
+ it "should have a nil instance" do
102
+ @feed.crawler.should be_nil
103
+ end
104
+
105
+ it "should accept a new instance" do
106
+ crawler = Crawler.create :host => 'foo.example.com'
107
+ @feed.crawler = crawler
108
+
109
+ @feed.links.should == [{ 'rel' => 'crawler', 'href' => crawler.id }]
110
+ @feed.save!
111
+
112
+ NewsFeed.get( @feed.id ).links.should == [{ 'rel' => 'crawler', 'href' => crawler.id }]
113
+ end
114
+
115
+ it "should load the object from the association" do
116
+ crawler = Crawler.create :host => 'foo.example.com'
117
+ @feed.crawler = crawler
118
+ @feed.save!
119
+
120
+ @feed.crawler.should == crawler
121
+ end
122
+
123
+ it "should give access to the raw association" do
124
+ crawler = Crawler.create :host => 'foo.example.com'
125
+ @feed.crawler = crawler
126
+ @feed.save!
127
+
128
+ @feed.crawler( true ).should == { 'rel' => 'crawler', 'href' => crawler.id }
129
+ end
130
+ end
131
+
132
+ end
@@ -0,0 +1,8 @@
1
+ class Article < ActiveRecord::Base
2
+
3
+ include Correlate
4
+
5
+ related_to do
6
+ some :comments, :class => 'Comment'
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ class BlankDoc < CouchRest::ExtendedDocument
2
+
3
+ include Correlate
4
+ end
@@ -0,0 +1,11 @@
1
+ class Comment < CouchRest::ExtendedDocument
2
+
3
+ use_database DB
4
+
5
+ include Correlate
6
+ include CouchRest::Validation
7
+
8
+ related_to do
9
+ a :article, :class => 'Article', :required => true
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ # Students are enlisted into courses
2
+ class Course < CouchRest::ExtendedDocument
3
+
4
+ use_database DB
5
+ end
@@ -0,0 +1,6 @@
1
+ # Responsible for updating the news feeds
2
+ class Crawler < CouchRest::ExtendedDocument
3
+
4
+ use_database DB
5
+
6
+ end
@@ -0,0 +1,13 @@
1
+ # The news feeds read by a reader, and has a crawler that updates it
2
+ class NewsFeed < CouchRest::ExtendedDocument
3
+
4
+ include Correlate
5
+
6
+ use_database DB
7
+
8
+ property :url
9
+
10
+ related_to do
11
+ a :crawler, :class => 'Crawler'
12
+ end
13
+ end
@@ -0,0 +1,2 @@
1
+ #class Note < CouchRest::ExtendedDocument
2
+ #end
@@ -0,0 +1,11 @@
1
+ # Test on a 'simple social graph'
2
+ class Person < CouchRest::ExtendedDocument
3
+
4
+ use_database DB
5
+
6
+ include Correlate
7
+
8
+ related_to do
9
+ some :people, :class => 'Person', :rel => 'person'
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ #class Project < ActiveRecord::Base
2
+ #end
@@ -0,0 +1,11 @@
1
+ # A reader of articles from different feeds
2
+ class Reader < CouchRest::ExtendedDocument
3
+
4
+ include Correlate
5
+
6
+ use_database DB
7
+
8
+ related_to do
9
+ some :news_feeds, :class => 'NewsFeed', :rel => 'news_feed'
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ class Student < CouchRest::ExtendedDocument
2
+
3
+ use_database DB
4
+
5
+ include Correlate
6
+ include CouchRest::Validation
7
+
8
+ related_to do
9
+ some :enlistments, :class => 'Course', :rel => 'course', :requires => 1
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correlate::Links do
4
+ fixtures :person
5
+
6
+ before(:each) do
7
+ @blank = Correlate::Links.new( Person )
8
+
9
+ @links = Correlate::Links.new( Person )
10
+ @links << { 'rel' => 'foo', 'href' => 'bar' }
11
+ end
12
+
13
+ it "should be able to find by rel" do
14
+ @links.rel( 'foo' ).should == [{ 'rel' => 'foo', 'href' => 'bar' }]
15
+ end
16
+
17
+ it "should be able to replace by rel" do
18
+ @links.replace({ 'rel' => 'foo', 'href' => 'baz' })
19
+
20
+ @links.should == [{ 'rel' => 'foo', 'href' => 'baz' }]
21
+ end
22
+
23
+ it "should be able to delete by rel" do
24
+ @links.delete({ 'rel' => 'foo', 'href' => 'bar' })
25
+ @links.should be_empty
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correlate::Relationships do
4
+ fixtures :blank_doc
5
+
6
+ it "should be able to configure a class" do
7
+ relationships = lambda {
8
+ some :foo
9
+ }
10
+
11
+ Correlate::Relationships.configure!( BlankDoc, &relationships )
12
+
13
+ link_property = BlankDoc.properties.detect { |p| p.name == 'links' }
14
+ link_property.should_not be_nil
15
+ link_property.type.should == 'Correlate::Links'
16
+ end
17
+ end
18
+
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'correlate'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
8
+ require 'couchrest'
9
+ require 'activerecord_helper'
10
+
11
+ unless defined?( COUCHHOST )
12
+ COUCHHOST = "http://127.0.0.1:5984"
13
+ TESTDB = 'correlate-test'
14
+ TEST_SERVER = CouchRest.new
15
+ TEST_SERVER.default_database = TESTDB
16
+ DB = TEST_SERVER.database(TESTDB)
17
+ end
18
+
19
+ Spec::Runner.configure do |config|
20
+ config.before(:suite) do
21
+ reset_test_sqlitedb!
22
+ end
23
+
24
+ config.before(:all) do
25
+ reset_test_couchdb!
26
+ end
27
+ end
28
+
29
+ def fixtures( *args )
30
+ args.each do |file|
31
+ file = file.to_s
32
+ if File.exists?( File.join( File.dirname(__FILE__), 'fixtures', "#{file}.rb" ) )
33
+ require File.join( File.dirname(__FILE__), 'fixtures', file )
34
+ end
35
+ end
36
+ end
37
+
38
+ def reset_test_couchdb!
39
+ DB.recreate! rescue nil
40
+ DB
41
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Correlate do
4
+ describe "validations for 'some'" do
5
+ fixtures :student, :course
6
+
7
+ before(:each) do
8
+ @student = Student.new
9
+ end
10
+
11
+ it "should be enforced" do
12
+ @student.should_not be_valid
13
+ end
14
+
15
+ it "should be met" do
16
+ @student.enlistments << Course.create( :name => 'B.Sc Foo' )
17
+ @student.should be_valid
18
+ end
19
+ end
20
+
21
+ describe "validations for 'a'" do
22
+ fixtures :comment, :article
23
+
24
+ before(:each) do
25
+ @comment = Comment.new
26
+ end
27
+
28
+ it "should be enforced" do
29
+ @comment.should_not be_valid
30
+ end
31
+
32
+ it "should be met" do
33
+ article = Article.create( :title => 'Validating the system' )
34
+ @comment.article = article
35
+ @comment.should be_valid
36
+ end
37
+ end
38
+ end