openlogic-couchrest_model 1.0.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.
- data/.gitignore +11 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE +176 -0
- data/README.md +137 -0
- data/Rakefile +38 -0
- data/THANKS.md +21 -0
- data/VERSION +1 -0
- data/benchmarks/dirty.rb +118 -0
- data/couchrest_model.gemspec +36 -0
- data/history.md +309 -0
- data/init.rb +1 -0
- data/lib/couchrest/model.rb +10 -0
- data/lib/couchrest/model/associations.rb +231 -0
- data/lib/couchrest/model/base.rb +129 -0
- data/lib/couchrest/model/callbacks.rb +28 -0
- data/lib/couchrest/model/casted_array.rb +83 -0
- data/lib/couchrest/model/casted_by.rb +33 -0
- data/lib/couchrest/model/casted_hash.rb +84 -0
- data/lib/couchrest/model/class_proxy.rb +135 -0
- data/lib/couchrest/model/collection.rb +273 -0
- data/lib/couchrest/model/configuration.rb +67 -0
- data/lib/couchrest/model/connection.rb +70 -0
- data/lib/couchrest/model/core_extensions/hash.rb +9 -0
- data/lib/couchrest/model/core_extensions/time_parsing.rb +66 -0
- data/lib/couchrest/model/design_doc.rb +128 -0
- data/lib/couchrest/model/designs.rb +91 -0
- data/lib/couchrest/model/designs/view.rb +513 -0
- data/lib/couchrest/model/dirty.rb +39 -0
- data/lib/couchrest/model/document_queries.rb +99 -0
- data/lib/couchrest/model/embeddable.rb +78 -0
- data/lib/couchrest/model/errors.rb +25 -0
- data/lib/couchrest/model/extended_attachments.rb +83 -0
- data/lib/couchrest/model/persistence.rb +178 -0
- data/lib/couchrest/model/properties.rb +228 -0
- data/lib/couchrest/model/property.rb +114 -0
- data/lib/couchrest/model/property_protection.rb +71 -0
- data/lib/couchrest/model/proxyable.rb +183 -0
- data/lib/couchrest/model/support/couchrest_database.rb +13 -0
- data/lib/couchrest/model/support/couchrest_design.rb +33 -0
- data/lib/couchrest/model/typecast.rb +154 -0
- data/lib/couchrest/model/validations.rb +80 -0
- data/lib/couchrest/model/validations/casted_model.rb +16 -0
- data/lib/couchrest/model/validations/locale/en.yml +5 -0
- data/lib/couchrest/model/validations/uniqueness.rb +69 -0
- data/lib/couchrest/model/views.rb +151 -0
- data/lib/couchrest/railtie.rb +24 -0
- data/lib/couchrest_model.rb +66 -0
- data/lib/rails/generators/couchrest_model.rb +16 -0
- data/lib/rails/generators/couchrest_model/config/config_generator.rb +18 -0
- data/lib/rails/generators/couchrest_model/config/templates/couchdb.yml +21 -0
- data/lib/rails/generators/couchrest_model/model/model_generator.rb +27 -0
- data/lib/rails/generators/couchrest_model/model/templates/model.rb +2 -0
- data/spec/.gitignore +1 -0
- data/spec/fixtures/attachments/README +3 -0
- data/spec/fixtures/attachments/couchdb.png +0 -0
- data/spec/fixtures/attachments/test.html +11 -0
- data/spec/fixtures/config/couchdb.yml +10 -0
- data/spec/fixtures/models/article.rb +36 -0
- data/spec/fixtures/models/base.rb +164 -0
- data/spec/fixtures/models/card.rb +19 -0
- data/spec/fixtures/models/cat.rb +23 -0
- data/spec/fixtures/models/client.rb +6 -0
- data/spec/fixtures/models/course.rb +27 -0
- data/spec/fixtures/models/event.rb +8 -0
- data/spec/fixtures/models/invoice.rb +14 -0
- data/spec/fixtures/models/key_chain.rb +5 -0
- data/spec/fixtures/models/membership.rb +4 -0
- data/spec/fixtures/models/person.rb +11 -0
- data/spec/fixtures/models/project.rb +6 -0
- data/spec/fixtures/models/question.rb +7 -0
- data/spec/fixtures/models/sale_entry.rb +9 -0
- data/spec/fixtures/models/sale_invoice.rb +14 -0
- data/spec/fixtures/models/service.rb +10 -0
- data/spec/fixtures/models/user.rb +22 -0
- data/spec/fixtures/views/lib.js +3 -0
- data/spec/fixtures/views/test_view/lib.js +3 -0
- data/spec/fixtures/views/test_view/only-map.js +4 -0
- data/spec/fixtures/views/test_view/test-map.js +3 -0
- data/spec/fixtures/views/test_view/test-reduce.js +3 -0
- data/spec/functional/validations_spec.rb +8 -0
- data/spec/spec_helper.rb +60 -0
- data/spec/unit/active_model_lint_spec.rb +30 -0
- data/spec/unit/assocations_spec.rb +242 -0
- data/spec/unit/attachment_spec.rb +176 -0
- data/spec/unit/base_spec.rb +537 -0
- data/spec/unit/casted_spec.rb +72 -0
- data/spec/unit/class_proxy_spec.rb +167 -0
- data/spec/unit/collection_spec.rb +86 -0
- data/spec/unit/configuration_spec.rb +77 -0
- data/spec/unit/connection_spec.rb +148 -0
- data/spec/unit/core_extensions/time_parsing.rb +77 -0
- data/spec/unit/design_doc_spec.rb +241 -0
- data/spec/unit/designs/view_spec.rb +831 -0
- data/spec/unit/designs_spec.rb +134 -0
- data/spec/unit/dirty_spec.rb +436 -0
- data/spec/unit/embeddable_spec.rb +498 -0
- data/spec/unit/inherited_spec.rb +33 -0
- data/spec/unit/persistence_spec.rb +481 -0
- data/spec/unit/property_protection_spec.rb +192 -0
- data/spec/unit/property_spec.rb +481 -0
- data/spec/unit/proxyable_spec.rb +376 -0
- data/spec/unit/subclass_spec.rb +85 -0
- data/spec/unit/typecast_spec.rb +521 -0
- data/spec/unit/validations_spec.rb +140 -0
- data/spec/unit/view_spec.rb +367 -0
- metadata +301 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'question'
|
|
2
|
+
require 'person'
|
|
3
|
+
|
|
4
|
+
class Course < CouchRest::Model::Base
|
|
5
|
+
use_database TEST_SERVER.default_database
|
|
6
|
+
|
|
7
|
+
property :title, String
|
|
8
|
+
property :questions, [Question]
|
|
9
|
+
property :professor, Person
|
|
10
|
+
property :participants, [Object]
|
|
11
|
+
property :ends_at, Time
|
|
12
|
+
property :estimate, Float
|
|
13
|
+
property :hours, Integer
|
|
14
|
+
property :profit, BigDecimal
|
|
15
|
+
property :started_on, :type => Date
|
|
16
|
+
property :updated_at, DateTime
|
|
17
|
+
property :active, :type => TrueClass
|
|
18
|
+
property :very_active, :type => TrueClass
|
|
19
|
+
property :klass, :type => Class
|
|
20
|
+
|
|
21
|
+
view_by :title
|
|
22
|
+
view_by :title, :active
|
|
23
|
+
view_by :dept, :ducktype => true
|
|
24
|
+
|
|
25
|
+
view_by :active, :map => "function(d) { if (d['#{model_type_key}'] == 'Course' && d['active']) { emit(d['updated_at'], 1); }}", :reduce => "function(k,v,r) { return sum(v); }"
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class Invoice < CouchRest::Model::Base
|
|
2
|
+
# Set the default database to use
|
|
3
|
+
use_database DB
|
|
4
|
+
|
|
5
|
+
# Official Schema
|
|
6
|
+
property :client_name
|
|
7
|
+
property :employee_name
|
|
8
|
+
property :location
|
|
9
|
+
|
|
10
|
+
# Validation
|
|
11
|
+
validates_presence_of :client_name, :employee_name
|
|
12
|
+
validates_presence_of :location, :message => "Hey stupid!, you forgot the location"
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
require 'client'
|
|
2
|
+
require 'sale_entry'
|
|
3
|
+
|
|
4
|
+
class SaleInvoice < CouchRest::Model::Base
|
|
5
|
+
use_database DB
|
|
6
|
+
|
|
7
|
+
belongs_to :client
|
|
8
|
+
belongs_to :alternate_client, :class_name => 'Client', :foreign_key => 'alt_client_id'
|
|
9
|
+
|
|
10
|
+
collection_of :entries, :class_name => 'SaleEntry'
|
|
11
|
+
|
|
12
|
+
property :date, Date
|
|
13
|
+
property :price, Integer
|
|
14
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class User < CouchRest::Model::Base
|
|
2
|
+
# Set the default database to use
|
|
3
|
+
use_database DB
|
|
4
|
+
property :name, :accessible => true
|
|
5
|
+
property :admin # this will be automatically protected
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class SpecialUser < CouchRest::Model::Base
|
|
9
|
+
# Set the default database to use
|
|
10
|
+
use_database DB
|
|
11
|
+
property :name # this will not be protected
|
|
12
|
+
property :admin, :protected => true
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# There are two modes of protection
|
|
16
|
+
# 1) Declare accessible poperties, assume all the rest are protected
|
|
17
|
+
# property :name, :accessible => true
|
|
18
|
+
# property :admin # this will be automatically protected
|
|
19
|
+
#
|
|
20
|
+
# 2) Declare protected properties, assume all the rest are accessible
|
|
21
|
+
# property :name # this will not be protected
|
|
22
|
+
# property :admin, :protected => true
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "rubygems"
|
|
6
|
+
require "rspec"
|
|
7
|
+
|
|
8
|
+
require 'couchrest_model'
|
|
9
|
+
|
|
10
|
+
unless defined?(FIXTURE_PATH)
|
|
11
|
+
MODEL_PATH = File.join(File.dirname(__FILE__), "fixtures", "models")
|
|
12
|
+
$LOAD_PATH.unshift(MODEL_PATH)
|
|
13
|
+
|
|
14
|
+
FIXTURE_PATH = File.join(File.dirname(__FILE__), '/fixtures')
|
|
15
|
+
SCRATCH_PATH = File.join(File.dirname(__FILE__), '/tmp')
|
|
16
|
+
|
|
17
|
+
COUCHHOST = "http://127.0.0.1:5984"
|
|
18
|
+
TESTDB = 'couchrest-model-test'
|
|
19
|
+
TEST_SERVER = CouchRest.new COUCHHOST
|
|
20
|
+
TEST_SERVER.default_database = TESTDB
|
|
21
|
+
DB = TEST_SERVER.database(TESTDB)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
RSpec.configure do |config|
|
|
25
|
+
config.before(:all) { reset_test_db! }
|
|
26
|
+
|
|
27
|
+
config.after(:all) do
|
|
28
|
+
cr = TEST_SERVER
|
|
29
|
+
test_dbs = cr.databases.select { |db| db =~ /^#{TESTDB}/ }
|
|
30
|
+
test_dbs.each do |db|
|
|
31
|
+
cr.database(db).delete! rescue nil
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Require each of the fixture models
|
|
37
|
+
Dir[ File.join(MODEL_PATH, "*.rb") ].sort.each { |file| require File.basename(file) }
|
|
38
|
+
|
|
39
|
+
class Basic < CouchRest::Model::Base
|
|
40
|
+
use_database TEST_SERVER.default_database
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def reset_test_db!
|
|
44
|
+
DB.recreate! rescue nil
|
|
45
|
+
# Reset the Design Cache
|
|
46
|
+
Thread.current[:couchrest_design_cache] = {}
|
|
47
|
+
DB
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def couchdb_lucene_available?
|
|
52
|
+
lucene_path = "http://localhost:5985/"
|
|
53
|
+
url = URI.parse(lucene_path)
|
|
54
|
+
req = Net::HTTP::Get.new(url.path)
|
|
55
|
+
res = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
|
|
56
|
+
true
|
|
57
|
+
rescue Exception => e
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'test/unit/assertions'
|
|
4
|
+
require 'active_model/lint'
|
|
5
|
+
|
|
6
|
+
class CompliantModel < CouchRest::Model::Base
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
describe CouchRest::Model::Base do
|
|
11
|
+
include Test::Unit::Assertions
|
|
12
|
+
include ActiveModel::Lint::Tests
|
|
13
|
+
|
|
14
|
+
before :each do
|
|
15
|
+
@model = CompliantModel.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "active model lint tests" do
|
|
19
|
+
ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
|
|
20
|
+
example m.gsub('_',' ') do
|
|
21
|
+
send m
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def model
|
|
27
|
+
@model
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
describe "Assocations" do
|
|
5
|
+
|
|
6
|
+
describe ".merge_belongs_to_association_options" do
|
|
7
|
+
before :all do
|
|
8
|
+
def SaleInvoice.merge_assoc_opts(*args)
|
|
9
|
+
merge_belongs_to_association_options(*args)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should return a default set of options" do
|
|
14
|
+
o = SaleInvoice.merge_assoc_opts(:cat)
|
|
15
|
+
o[:foreign_key].should eql('cat_id')
|
|
16
|
+
o[:class_name].should eql('Cat')
|
|
17
|
+
o[:proxy_name].should eql('cats')
|
|
18
|
+
o[:proxy].should eql('Cat') # same as class name
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should merge with provided options" do
|
|
22
|
+
o = SaleInvoice.merge_assoc_opts(:cat, :foreign_key => 'somecat_id', :proxy => 'some_cats')
|
|
23
|
+
o[:foreign_key].should eql('somecat_id')
|
|
24
|
+
o[:proxy].should eql('some_cats')
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should generate a proxy string if proxied" do
|
|
28
|
+
SaleInvoice.stub!(:proxy_owner_method).twice.and_return('company')
|
|
29
|
+
o = SaleInvoice.merge_assoc_opts(:cat)
|
|
30
|
+
o[:proxy].should eql('self.company.cats')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "of type belongs to" do
|
|
36
|
+
|
|
37
|
+
before :each do
|
|
38
|
+
@invoice = SaleInvoice.create(:price => 2000)
|
|
39
|
+
@client = Client.create(:name => "Sam Lown")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should create a foreign key property with setter and getter" do
|
|
43
|
+
@invoice.properties.find{|p| p.name == 'client_id'}.should_not be_nil
|
|
44
|
+
@invoice.respond_to?(:client_id).should be_true
|
|
45
|
+
@invoice.respond_to?("client_id=").should be_true
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "should set the property and provide object when set" do
|
|
49
|
+
@invoice.client = @client
|
|
50
|
+
@invoice.client_id.should eql(@client.id)
|
|
51
|
+
@invoice.client.should eql(@client)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "should set the attribute, save and return" do
|
|
55
|
+
@invoice.client = @client
|
|
56
|
+
@invoice.save
|
|
57
|
+
@invoice = SaleInvoice.get(@invoice.id)
|
|
58
|
+
@invoice.client.id.should eql(@client.id)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "should remove the association if nil is provided" do
|
|
62
|
+
@invoice.client = @client
|
|
63
|
+
@invoice.client = nil
|
|
64
|
+
@invoice.client_id.should be_nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "should not try to search for association if foreign_key is nil" do
|
|
68
|
+
@invoice.client_id = nil
|
|
69
|
+
Client.should_not_receive(:get)
|
|
70
|
+
@invoice.client
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "should allow override of foreign key" do
|
|
74
|
+
@invoice.respond_to?(:alternate_client).should be_true
|
|
75
|
+
@invoice.respond_to?("alternate_client=").should be_true
|
|
76
|
+
@invoice.properties.find{|p| p.name == 'alt_client_id'}.should_not be_nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "should allow override of foreign key and save" do
|
|
80
|
+
@invoice.alternate_client = @client
|
|
81
|
+
@invoice.save
|
|
82
|
+
@invoice = SaleInvoice.get(@invoice.id)
|
|
83
|
+
@invoice.alternate_client.id.should eql(@client.id)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe "of type collection_of" do
|
|
89
|
+
|
|
90
|
+
before(:each) do
|
|
91
|
+
@invoice = SaleInvoice.create(:price => 2000)
|
|
92
|
+
@entries = [
|
|
93
|
+
SaleEntry.create(:description => 'test line 1', :price => 500),
|
|
94
|
+
SaleEntry.create(:description => 'test line 2', :price => 500),
|
|
95
|
+
SaleEntry.create(:description => 'test line 3', :price => 1000)
|
|
96
|
+
]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it "should create an associated property and collection proxy" do
|
|
100
|
+
@invoice.respond_to?('entry_ids').should be_true
|
|
101
|
+
@invoice.respond_to?('entry_ids=').should be_true
|
|
102
|
+
@invoice.entries.class.should eql(::CouchRest::Model::CollectionOfProxy)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "should allow replacement of objects" do
|
|
106
|
+
@invoice.entries = @entries
|
|
107
|
+
@invoice.entries.length.should eql(3)
|
|
108
|
+
@invoice.entry_ids.length.should eql(3)
|
|
109
|
+
@invoice.entries.first.should eql(@entries.first)
|
|
110
|
+
@invoice.entry_ids.first.should eql(@entries.first.id)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should allow ids to be set directly and load entries" do
|
|
114
|
+
@invoice.entry_ids = @entries.collect{|i| i.id}
|
|
115
|
+
@invoice.entries.length.should eql(3)
|
|
116
|
+
@invoice.entries.first.should eql(@entries.first)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "should replace collection if ids replaced" do
|
|
120
|
+
@invoice.entry_ids = @entries.collect{|i| i.id}
|
|
121
|
+
@invoice.entries.length.should eql(3) # load once
|
|
122
|
+
@invoice.entry_ids = @entries[0..1].collect{|i| i.id}
|
|
123
|
+
@invoice.entries.length.should eql(2)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "should allow forced collection update if ids changed" do
|
|
127
|
+
@invoice.entry_ids = @entries[0..1].collect{|i| i.id}
|
|
128
|
+
@invoice.entries.length.should eql(2) # load once
|
|
129
|
+
@invoice.entry_ids << @entries[2].id
|
|
130
|
+
@invoice.entry_ids.length.should eql(3)
|
|
131
|
+
@invoice.entries.length.should eql(2) # cached!
|
|
132
|
+
@invoice.entries(true).length.should eql(3)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
it "should empty arrays when nil collection provided" do
|
|
136
|
+
@invoice.entries = @entries
|
|
137
|
+
@invoice.entries = nil
|
|
138
|
+
@invoice.entry_ids.should be_empty
|
|
139
|
+
@invoice.entries.should be_empty
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should empty arrays when nil ids array provided" do
|
|
143
|
+
@invoice.entries = @entries
|
|
144
|
+
@invoice.entry_ids = nil
|
|
145
|
+
@invoice.entry_ids.should be_empty
|
|
146
|
+
@invoice.entries.should be_empty
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "should ignore nil entries" do
|
|
150
|
+
@invoice.entries = [ nil ]
|
|
151
|
+
@invoice.entry_ids.should be_empty
|
|
152
|
+
@invoice.entries.should be_empty
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Account for dirty tracking
|
|
156
|
+
describe "dirty tracking" do
|
|
157
|
+
it "should register changes on push" do
|
|
158
|
+
@invoice.changed?.should be_false
|
|
159
|
+
@invoice.entries << @entries[0]
|
|
160
|
+
@invoice.changed?.should be_true
|
|
161
|
+
end
|
|
162
|
+
it "should register changes on pop" do
|
|
163
|
+
@invoice.entries << @entries[0]
|
|
164
|
+
@invoice.save
|
|
165
|
+
@invoice.changed?.should be_false
|
|
166
|
+
@invoice.entries.pop
|
|
167
|
+
@invoice.changed?.should be_true
|
|
168
|
+
end
|
|
169
|
+
it "should register id changes on push" do
|
|
170
|
+
@invoice.entry_ids << @entries[0].id
|
|
171
|
+
@invoice.changed?.should be_true
|
|
172
|
+
end
|
|
173
|
+
it "should register id changes on pop" do
|
|
174
|
+
@invoice.entry_ids << @entries[0].id
|
|
175
|
+
@invoice.save
|
|
176
|
+
@invoice.changed?.should be_false
|
|
177
|
+
@invoice.entry_ids.pop
|
|
178
|
+
@invoice.changed?.should be_true
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
describe "proxy" do
|
|
183
|
+
|
|
184
|
+
it "should ensure new entries to proxy are matched" do
|
|
185
|
+
@invoice.entries << @entries.first
|
|
186
|
+
@invoice.entry_ids.first.should eql(@entries.first.id)
|
|
187
|
+
@invoice.entries.first.should eql(@entries.first)
|
|
188
|
+
@invoice.entries << @entries[1]
|
|
189
|
+
@invoice.entries.count.should eql(2)
|
|
190
|
+
@invoice.entry_ids.count.should eql(2)
|
|
191
|
+
@invoice.entry_ids.last.should eql(@entries[1].id)
|
|
192
|
+
@invoice.entries.last.should eql(@entries[1])
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "should support push method" do
|
|
196
|
+
@invoice.entries.push(@entries.first)
|
|
197
|
+
@invoice.entry_ids.first.should eql(@entries.first.id)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should support []= method" do
|
|
201
|
+
@invoice.entries[0] = @entries.first
|
|
202
|
+
@invoice.entry_ids.first.should eql(@entries.first.id)
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
it "should support unshift method" do
|
|
206
|
+
@invoice.entries.unshift(@entries.first)
|
|
207
|
+
@invoice.entry_ids.first.should eql(@entries.first.id)
|
|
208
|
+
@invoice.entries.unshift(@entries[1])
|
|
209
|
+
@invoice.entry_ids.first.should eql(@entries[1].id)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "should support pop method" do
|
|
213
|
+
@invoice.entries.push(@entries.first)
|
|
214
|
+
@invoice.entries.pop.should eql(@entries.first)
|
|
215
|
+
@invoice.entries.empty?.should be_true
|
|
216
|
+
@invoice.entry_ids.empty?.should be_true
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
it "should support shift method" do
|
|
220
|
+
@invoice.entries.push(@entries[0])
|
|
221
|
+
@invoice.entries.push(@entries[1])
|
|
222
|
+
@invoice.entries.shift.should eql(@entries[0])
|
|
223
|
+
@invoice.entries.first.should eql(@entries[1])
|
|
224
|
+
@invoice.entry_ids.first.should eql(@entries[1].id)
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it "should raise error when adding un-persisted entries" do
|
|
228
|
+
SaleEntry.find_by_description('test entry').should be_nil
|
|
229
|
+
entry = SaleEntry.new(:description => 'test entry', :price => 500)
|
|
230
|
+
lambda {
|
|
231
|
+
@invoice.entries << entry
|
|
232
|
+
}.should raise_error
|
|
233
|
+
# In the future maybe?
|
|
234
|
+
# @invoice.save.should be_true
|
|
235
|
+
# SaleEntry.find_by_description('test entry').should_not be_nil
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
end
|