dm-ambition 0.10.2

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,23 @@
1
+ module DataMapper
2
+ module Ambition
3
+ module Query
4
+ @@sexps = {}
5
+
6
+ # TODO: spec and document this
7
+ # @api semipublic
8
+ def filter(negated = false, &block)
9
+ # TODO: benchmark Marshal versus just building the sexp on demand
10
+
11
+ # deep clone the sexp for multiple re-use
12
+ sexp = Marshal.load(@@sexps[block.to_s] ||= Marshal.dump(block.to_sexp))
13
+
14
+ processor = FilterProcessor.new(block.binding, model, negated)
15
+ processor.process(sexp)
16
+
17
+ merge(:conditions => processor.conditions)
18
+ end
19
+ end # module Query
20
+ end # module Ambition
21
+ end # module DataMapper
22
+
23
+ require Pathname(__FILE__).dirname.expand_path / 'query' / 'filter_processor'
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Ambition
3
+ VERSION = '0.10.2'.freeze
4
+ end
5
+ end
@@ -0,0 +1,50 @@
1
+ require 'pathname'
2
+
3
+ dir = Pathname(__FILE__).dirname.expand_path + 'dm-ambition'
4
+
5
+ require dir / 'collection'
6
+ require dir / 'model'
7
+ require dir / 'query'
8
+ require dir / 'version'
9
+
10
+ module DataMapper
11
+ class Collection
12
+ include Ambition::Collection
13
+ end
14
+
15
+ module Model
16
+ include Ambition::Model
17
+ end
18
+
19
+ class Query
20
+ include Ambition::Query
21
+ end
22
+
23
+ if Gem::Version.new(DataMapper::VERSION) < Gem::Version.new('0.10')
24
+ module Model
25
+ def self.descendants
26
+ Resource.descendants
27
+ end
28
+ end
29
+
30
+ class Collection
31
+ def new_collection(query, resources = nil, &block)
32
+ collection = self.class.new(query, &block)
33
+
34
+ if resources
35
+ collection.replace(resources)
36
+ end
37
+
38
+ collection
39
+ end
40
+ end
41
+
42
+ module Resource
43
+ def saved?
44
+ !new_record?
45
+ end
46
+
47
+ alias new? new_record?
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,138 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ [ false, true ].each do |loaded|
5
+ describe DataMapper::Ambition::Collection do
6
+ cattr_accessor :loaded
7
+
8
+ self.loaded = loaded
9
+
10
+ before :all do
11
+ class ::User
12
+ include DataMapper::Resource
13
+
14
+ property :id, Serial
15
+ property :name, String
16
+ property :admin, Boolean, :default => false
17
+ end
18
+
19
+ if DataMapper.respond_to?(:auto_migrate!)
20
+ DataMapper.auto_migrate!
21
+ end
22
+ end
23
+
24
+ before :all do
25
+ @repository = DataMapper.repository(:default)
26
+ @model = User
27
+ @query = DataMapper::Query.new(@repository, @model)
28
+
29
+ @user = @model.create(:name => 'Dan Kubb', :admin => true)
30
+ @other = @model.create(:name => 'Sam Smoot')
31
+
32
+ @subject = @model.all(@query)
33
+ @subject.to_a if loaded
34
+ end
35
+
36
+ it_should_behave_like 'it has public filter methods'
37
+
38
+ unless loaded || Gem::Version.new(DataMapper::VERSION) < Gem::Version.new('0.10')
39
+ [ :select, :find_all ].each do |method|
40
+ describe "##{method}", '(unloaded)' do
41
+ describe 'when matching resource prepended' do
42
+ before :all do
43
+ @subject.unshift(@other)
44
+ @return = @subject.send(method) { |u| u.admin == true }
45
+ end
46
+
47
+ it 'should return a Collection' do
48
+ @return.should be_kind_of(DataMapper::Collection)
49
+ end
50
+
51
+ it 'should not return self' do
52
+ @return.should_not equal(@subject)
53
+ end
54
+
55
+ it 'should not be a kicker' do
56
+ @return.should_not be_loaded
57
+ end
58
+
59
+ it 'should return expected values' do
60
+ @return.should == [ @user ]
61
+ end
62
+ end
63
+
64
+ describe 'when matching resource appended' do
65
+ before :all do
66
+ @subject << @other
67
+ @return = @subject.send(method) { |u| u.admin == true }
68
+ end
69
+
70
+ it 'should return a Collection' do
71
+ @return.should be_kind_of(DataMapper::Collection)
72
+ end
73
+
74
+ it 'should not return self' do
75
+ @return.should_not equal(@subject)
76
+ end
77
+
78
+ it 'should not be a kicker' do
79
+ @return.should_not be_loaded
80
+ end
81
+
82
+ it 'should return expected values' do
83
+ @return.should == [ @user ]
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '#reject', '(unloaded)' do
90
+ describe 'when matching resource prepended' do
91
+ before :all do
92
+ @subject.unshift(@other)
93
+ @return = @subject.reject { |u| u.admin != true }
94
+ end
95
+
96
+ it 'should return a Collection' do
97
+ @return.should be_kind_of(DataMapper::Collection)
98
+ end
99
+
100
+ it 'should not return self' do
101
+ @return.should_not equal(@subject)
102
+ end
103
+
104
+ it 'should not be a kicker' do
105
+ @return.should_not be_loaded
106
+ end
107
+
108
+ it 'should return expected values' do
109
+ @return.should == [ @user ]
110
+ end
111
+ end
112
+
113
+ describe 'when matching resource appended' do
114
+ before :all do
115
+ @subject << @other
116
+ @return = @subject.reject { |u| u.admin != true }
117
+ end
118
+
119
+ it 'should return a Collection' do
120
+ @return.should be_kind_of(DataMapper::Collection)
121
+ end
122
+
123
+ it 'should not return self' do
124
+ @return.should_not equal(@subject)
125
+ end
126
+
127
+ it 'should not be a kicker' do
128
+ @return.should_not be_loaded
129
+ end
130
+
131
+ it 'should return expected values' do
132
+ @return.should == [ @user ]
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,34 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
+
4
+ describe DataMapper::Ambition::Model do
5
+ def self.loaded
6
+ false
7
+ end
8
+
9
+ before :all do
10
+ class ::User
11
+ include DataMapper::Resource
12
+
13
+ property :id, Serial
14
+ property :name, String
15
+ property :admin, Boolean, :default => false
16
+ end
17
+
18
+ if DataMapper.respond_to?(:auto_migrate!)
19
+ DataMapper.auto_migrate!
20
+ end
21
+ end
22
+
23
+ before :all do
24
+ @repository = DataMapper.repository(:default)
25
+ @model = User
26
+
27
+ @user = @model.create(:name => 'Dan Kubb', :admin => true)
28
+ @other = @model.create(:name => 'Sam Smoot')
29
+
30
+ @subject = @model
31
+ end
32
+
33
+ it_should_behave_like 'it has public filter methods'
34
+ end
@@ -0,0 +1,221 @@
1
+ share_examples_for 'it has public filter methods' do
2
+ [ :select, :find_all ].each do |method|
3
+ it { @subject.should respond_to(method) }
4
+
5
+ describe "##{method}", ('(loaded)' if loaded) do
6
+ describe 'with simple conditions' do
7
+ before :all do
8
+ @return = @subject.send(method) { |u| u.name == 'Dan Kubb' }
9
+ end
10
+
11
+ it 'should return a Collection' do
12
+ @return.should be_kind_of(DataMapper::Collection)
13
+ end
14
+
15
+ it 'should not return self' do
16
+ @return.should_not equal(@subject)
17
+ end
18
+
19
+ unless loaded
20
+ it 'should not be a kicker' do
21
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
22
+ end
23
+ end
24
+
25
+ it 'should return expected values' do
26
+ @return.should == [ @user ]
27
+ end
28
+ end
29
+
30
+ describe 'with OR + AND conditions' do
31
+ before :all do
32
+ @return = @subject.send(method) { |u| (u.name == 'Dan Kubb' || u.name == 'Sam Smoot') && u.admin == true }
33
+ end
34
+
35
+ it 'should return a Collection' do
36
+ @return.should be_kind_of(DataMapper::Collection)
37
+ end
38
+
39
+ it 'should not return self' do
40
+ @return.should_not equal(@subject)
41
+ end
42
+
43
+ unless loaded
44
+ it 'should not be a kicker' do
45
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
46
+ end
47
+ end
48
+
49
+ it 'should return expected values' do
50
+ @return.should == [ @user ]
51
+ end
52
+ end
53
+
54
+ describe 'with AND + OR conditions' do
55
+ before :all do
56
+ @return = @subject.send(method) { |u| (u.admin == true && u.name == 'Dan Kubb') || u.name == 'Sam Smoot' }
57
+ end
58
+
59
+ it 'should return a Collection' do
60
+ @return.should be_kind_of(DataMapper::Collection)
61
+ end
62
+
63
+ it 'should not return self' do
64
+ @return.should_not equal(@subject)
65
+ end
66
+
67
+ unless loaded
68
+ it 'should not be a kicker' do
69
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
70
+ end
71
+ end
72
+
73
+ it 'should return expected values' do
74
+ @return.should == [ @user, @other ]
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ [ :detect, :find ].each do |method|
81
+ it { @subject.should respond_to(method) }
82
+
83
+ describe "##{method}", ('(loaded)' if loaded) do
84
+ describe 'with simple conditions' do
85
+ before :all do
86
+ @return = @subject.send(method) { |u| u.name == 'Dan Kubb' }
87
+ end
88
+
89
+ it 'should return a Resource' do
90
+ @return.should be_kind_of(DataMapper::Resource)
91
+ end
92
+
93
+ unless loaded
94
+ it 'should not be a kicker' do
95
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
96
+ end
97
+ end
98
+
99
+ it 'should return expected value' do
100
+ @return.should == @user
101
+ end
102
+ end
103
+
104
+ describe 'with OR + AND conditions' do
105
+ before :all do
106
+ @return = @subject.send(method) { |u| (u.name == 'Dan Kubb' || u.name == 'Sam Smoot') && u.admin == true }
107
+ end
108
+
109
+ it 'should return a Resource' do
110
+ @return.should be_kind_of(DataMapper::Resource)
111
+ end
112
+
113
+ unless loaded
114
+ it 'should not be a kicker' do
115
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
116
+ end
117
+ end
118
+
119
+ it 'should return expected value' do
120
+ @return.should == @user
121
+ end
122
+ end
123
+
124
+ describe 'with AND + OR conditions' do
125
+ before :all do
126
+ @return = @subject.send(method) { |u| (u.admin == true && u.name == 'Dan Kubb') || u.name == 'Sam Smoot' }
127
+ end
128
+
129
+ it 'should return a Resource' do
130
+ @return.should be_kind_of(DataMapper::Resource)
131
+ end
132
+
133
+ unless loaded
134
+ it 'should not be a kicker' do
135
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
136
+ end
137
+ end
138
+
139
+ it 'should return expected value' do
140
+ @return.should == @user
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ it { @subject.should respond_to(:reject) }
147
+
148
+ describe '#reject', ('(loaded)' if loaded) do
149
+ describe 'with simple conditions' do
150
+ before :all do
151
+ @return = @subject.reject { |u| u.name != 'Dan Kubb' }
152
+ end
153
+
154
+ it 'should return a Collection' do
155
+ @return.should be_kind_of(DataMapper::Collection)
156
+ end
157
+
158
+ it 'should not return self' do
159
+ @return.should_not equal(@subject)
160
+ end
161
+
162
+ unless loaded
163
+ it 'should not be a kicker' do
164
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
165
+ end
166
+ end
167
+
168
+ it 'should return expected values' do
169
+ @return.should == [ @user ]
170
+ end
171
+ end
172
+
173
+ describe 'with OR + AND conditions' do
174
+ before :all do
175
+ @return = @subject.reject { |u| (u.name == 'Dan Kubb' || u.name == 'Sam Smoot') && u.admin == true }
176
+ end
177
+
178
+ it 'should return a Collection' do
179
+ @return.should be_kind_of(DataMapper::Collection)
180
+ end
181
+
182
+ it 'should not return self' do
183
+ @return.should_not equal(@subject)
184
+ end
185
+
186
+ unless loaded
187
+ it 'should not be a kicker' do
188
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
189
+ end
190
+ end
191
+
192
+ it 'should return expected values' do
193
+ @return.should == [ @other ]
194
+ end
195
+ end
196
+
197
+ describe 'with AND + OR conditions' do
198
+ before :all do
199
+ @return = @subject.reject { |u| (u.admin == true && u.name == 'Dan Kubb') || u.name == 'Sam Smoot' }
200
+ end
201
+
202
+ it 'should return a Collection' do
203
+ @return.should be_kind_of(DataMapper::Collection)
204
+ end
205
+
206
+ it 'should not return self' do
207
+ @return.should_not equal(@subject)
208
+ end
209
+
210
+ unless loaded
211
+ it 'should not be a kicker' do
212
+ @subject.respond_to?(:loaded) and @subject.should_not be_loaded
213
+ end
214
+ end
215
+
216
+ it 'should return expected values' do
217
+ @return.should == []
218
+ end
219
+ end
220
+ end
221
+ end