arel 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.
- data/.gitignore +6 -0
- data/README.markdown +184 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/arel.gemspec +233 -0
- data/doc/CONVENTIONS +17 -0
- data/doc/TODO +118 -0
- data/lib/arel.rb +10 -0
- data/lib/arel/algebra.rb +4 -0
- data/lib/arel/algebra/extensions.rb +4 -0
- data/lib/arel/algebra/extensions/class.rb +32 -0
- data/lib/arel/algebra/extensions/hash.rb +11 -0
- data/lib/arel/algebra/extensions/object.rb +17 -0
- data/lib/arel/algebra/extensions/symbol.rb +9 -0
- data/lib/arel/algebra/predicates.rb +41 -0
- data/lib/arel/algebra/primitives.rb +5 -0
- data/lib/arel/algebra/primitives/attribute.rb +150 -0
- data/lib/arel/algebra/primitives/expression.rb +43 -0
- data/lib/arel/algebra/primitives/ordering.rb +23 -0
- data/lib/arel/algebra/primitives/value.rb +14 -0
- data/lib/arel/algebra/relations.rb +14 -0
- data/lib/arel/algebra/relations/operations/alias.rb +7 -0
- data/lib/arel/algebra/relations/operations/group.rb +12 -0
- data/lib/arel/algebra/relations/operations/join.rb +64 -0
- data/lib/arel/algebra/relations/operations/order.rb +18 -0
- data/lib/arel/algebra/relations/operations/project.rb +20 -0
- data/lib/arel/algebra/relations/operations/skip.rb +6 -0
- data/lib/arel/algebra/relations/operations/take.rb +10 -0
- data/lib/arel/algebra/relations/operations/where.rb +16 -0
- data/lib/arel/algebra/relations/relation.rb +136 -0
- data/lib/arel/algebra/relations/row.rb +26 -0
- data/lib/arel/algebra/relations/utilities/compound.rb +30 -0
- data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
- data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
- data/lib/arel/algebra/relations/writes.rb +36 -0
- data/lib/arel/engines.rb +2 -0
- data/lib/arel/engines/memory.rb +4 -0
- data/lib/arel/engines/memory/engine.rb +16 -0
- data/lib/arel/engines/memory/predicates.rb +35 -0
- data/lib/arel/engines/memory/primitives.rb +27 -0
- data/lib/arel/engines/memory/relations.rb +5 -0
- data/lib/arel/engines/memory/relations/array.rb +25 -0
- data/lib/arel/engines/memory/relations/compound.rb +9 -0
- data/lib/arel/engines/memory/relations/operations.rb +61 -0
- data/lib/arel/engines/memory/relations/writes.rb +7 -0
- data/lib/arel/engines/sql.rb +7 -0
- data/lib/arel/engines/sql/christener.rb +13 -0
- data/lib/arel/engines/sql/engine.rb +37 -0
- data/lib/arel/engines/sql/extensions.rb +4 -0
- data/lib/arel/engines/sql/extensions/array.rb +16 -0
- data/lib/arel/engines/sql/extensions/nil_class.rb +11 -0
- data/lib/arel/engines/sql/extensions/object.rb +15 -0
- data/lib/arel/engines/sql/extensions/range.rb +15 -0
- data/lib/arel/engines/sql/formatters.rb +113 -0
- data/lib/arel/engines/sql/predicates.rb +51 -0
- data/lib/arel/engines/sql/primitives.rb +85 -0
- data/lib/arel/engines/sql/relations.rb +9 -0
- data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
- data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
- data/lib/arel/engines/sql/relations/relation.rb +50 -0
- data/lib/arel/engines/sql/relations/table.rb +52 -0
- data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
- data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
- data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
- data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
- data/lib/arel/engines/sql/relations/writes.rb +39 -0
- data/lib/arel/session.rb +48 -0
- data/spec/arel/algebra/unit/predicates/binary_spec.rb +33 -0
- data/spec/arel/algebra/unit/predicates/equality_spec.rb +27 -0
- data/spec/arel/algebra/unit/predicates/in_spec.rb +10 -0
- data/spec/arel/algebra/unit/primitives/attribute_spec.rb +183 -0
- data/spec/arel/algebra/unit/primitives/expression_spec.rb +45 -0
- data/spec/arel/algebra/unit/primitives/value_spec.rb +15 -0
- data/spec/arel/algebra/unit/relations/alias_spec.rb +16 -0
- data/spec/arel/algebra/unit/relations/delete_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/group_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/insert_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/join_spec.rb +26 -0
- data/spec/arel/algebra/unit/relations/order_spec.rb +21 -0
- data/spec/arel/algebra/unit/relations/project_spec.rb +34 -0
- data/spec/arel/algebra/unit/relations/relation_spec.rb +188 -0
- data/spec/arel/algebra/unit/relations/skip_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/table_spec.rb +39 -0
- data/spec/arel/algebra/unit/relations/take_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/update_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/where_spec.rb +18 -0
- data/spec/arel/algebra/unit/session/session_spec.rb +84 -0
- data/spec/arel/engines/memory/integration/joins/cross_engine_spec.rb +48 -0
- data/spec/arel/engines/memory/unit/relations/array_spec.rb +32 -0
- data/spec/arel/engines/memory/unit/relations/insert_spec.rb +28 -0
- data/spec/arel/engines/memory/unit/relations/join_spec.rb +31 -0
- data/spec/arel/engines/memory/unit/relations/order_spec.rb +27 -0
- data/spec/arel/engines/memory/unit/relations/project_spec.rb +27 -0
- data/spec/arel/engines/memory/unit/relations/skip_spec.rb +26 -0
- data/spec/arel/engines/memory/unit/relations/take_spec.rb +26 -0
- data/spec/arel/engines/memory/unit/relations/where_spec.rb +39 -0
- data/spec/arel/engines/sql/integration/joins/with_adjacency_spec.rb +209 -0
- data/spec/arel/engines/sql/integration/joins/with_aggregations_spec.rb +167 -0
- data/spec/arel/engines/sql/integration/joins/with_compounds_spec.rb +107 -0
- data/spec/arel/engines/sql/unit/engine_spec.rb +45 -0
- data/spec/arel/engines/sql/unit/predicates/binary_spec.rb +117 -0
- data/spec/arel/engines/sql/unit/predicates/equality_spec.rb +46 -0
- data/spec/arel/engines/sql/unit/predicates/in_spec.rb +86 -0
- data/spec/arel/engines/sql/unit/predicates/predicates_spec.rb +65 -0
- data/spec/arel/engines/sql/unit/primitives/attribute_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/primitives/expression_spec.rb +24 -0
- data/spec/arel/engines/sql/unit/primitives/literal_spec.rb +23 -0
- data/spec/arel/engines/sql/unit/primitives/value_spec.rb +29 -0
- data/spec/arel/engines/sql/unit/relations/alias_spec.rb +43 -0
- data/spec/arel/engines/sql/unit/relations/delete_spec.rb +63 -0
- data/spec/arel/engines/sql/unit/relations/group_spec.rb +56 -0
- data/spec/arel/engines/sql/unit/relations/insert_spec.rb +107 -0
- data/spec/arel/engines/sql/unit/relations/join_spec.rb +57 -0
- data/spec/arel/engines/sql/unit/relations/order_spec.rb +113 -0
- data/spec/arel/engines/sql/unit/relations/project_spec.rb +110 -0
- data/spec/arel/engines/sql/unit/relations/skip_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/relations/table_spec.rb +69 -0
- data/spec/arel/engines/sql/unit/relations/take_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/relations/update_spec.rb +151 -0
- data/spec/arel/engines/sql/unit/relations/where_spec.rb +56 -0
- data/spec/connections/mysql_connection.rb +16 -0
- data/spec/connections/postgresql_connection.rb +15 -0
- data/spec/connections/sqlite3_connection.rb +25 -0
- data/spec/doubles/hash.rb +23 -0
- data/spec/matchers/be_like.rb +24 -0
- data/spec/matchers/disambiguate_attributes.rb +28 -0
- data/spec/matchers/hash_the_same_as.rb +26 -0
- data/spec/schemas/mysql_schema.rb +18 -0
- data/spec/schemas/postgresql_schema.rb +18 -0
- data/spec/schemas/sqlite3_schema.rb +18 -0
- data/spec/spec_helper.rb +47 -0
- metadata +250 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Equality do
|
5
|
+
before do
|
6
|
+
@relation1 = Table.new(:users)
|
7
|
+
@relation2 = Table.new(:photos)
|
8
|
+
@attribute1 = @relation1[:id]
|
9
|
+
@attribute2 = @relation2[:user_id]
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '==' do
|
13
|
+
it "obtains if attribute1 and attribute2 are identical" do
|
14
|
+
Equality.new(@attribute1, @attribute2).should == Equality.new(@attribute1, @attribute2)
|
15
|
+
Equality.new(@attribute1, @attribute2).should_not == Equality.new(@attribute1, @attribute1)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "obtains if the concrete type of the predicates are identical" do
|
19
|
+
Equality.new(@attribute1, @attribute2).should_not == Binary.new(@attribute1, @attribute2)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "is commutative on the attributes" do
|
23
|
+
Equality.new(@attribute1, @attribute2).should == Equality.new(@attribute2, @attribute1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Attribute do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute = @relation[:id]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#inspect" do
|
11
|
+
it "returns a simple, short inspect string" do
|
12
|
+
@attribute.inspect.should == "<Attribute id>"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Attribute::Transformations do
|
17
|
+
describe '#as' do
|
18
|
+
it "manufactures an aliased attributed" do
|
19
|
+
@attribute.as(:alias).should == Attribute.new(@relation, @attribute.name, :alias => :alias, :ancestor => @attribute)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#bind' do
|
24
|
+
it "manufactures an attribute with the relation bound and self as an ancestor" do
|
25
|
+
derived_relation = @relation.where(@relation[:id].eq(1))
|
26
|
+
@attribute.bind(derived_relation).should == Attribute.new(derived_relation, @attribute.name, :ancestor => @attribute)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns self if the substituting to the same relation" do
|
30
|
+
@attribute.bind(@relation).should == @attribute
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '#to_attribute' do
|
35
|
+
describe 'when the given relation is the same as the attributes relation' do
|
36
|
+
it "returns self" do
|
37
|
+
@attribute.to_attribute(@relation).should == @attribute
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'when the given relation differs from the attributes relation' do
|
42
|
+
it 'binds to the new relation' do
|
43
|
+
@attribute.to_attribute(new_relation = @relation.alias).should == @attribute.bind(new_relation)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#column' do
|
50
|
+
it "returns the corresponding column in the relation" do
|
51
|
+
@attribute.column.should == @relation.column_for(@attribute)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#engine' do
|
56
|
+
it "delegates to its relation" do
|
57
|
+
Attribute.new(@relation, :id).engine.should == @relation.engine
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe Attribute::Congruence do
|
62
|
+
describe '/' do
|
63
|
+
before do
|
64
|
+
@aliased_relation = @relation.alias
|
65
|
+
@doubly_aliased_relation = @aliased_relation.alias
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'when dividing two unrelated attributes' do
|
69
|
+
it "returns 0.0" do
|
70
|
+
(@relation[:id] / @relation[:name]).should == 0.0
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'when dividing two matching attributes' do
|
75
|
+
it 'returns a the highest score for the most similar attributes' do
|
76
|
+
(@aliased_relation[:id] / @relation[:id]) \
|
77
|
+
.should == (@aliased_relation[:id] / @relation[:id])
|
78
|
+
(@aliased_relation[:id] / @relation[:id]) \
|
79
|
+
.should < (@aliased_relation[:id] / @aliased_relation[:id])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe Attribute::Predications do
|
86
|
+
before do
|
87
|
+
@attribute = Attribute.new(@relation, :name)
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '#eq' do
|
91
|
+
it "manufactures an equality predicate" do
|
92
|
+
@attribute.eq('name').should == Equality.new(@attribute, 'name')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#lt' do
|
97
|
+
it "manufactures a less-than predicate" do
|
98
|
+
@attribute.lt(10).should == LessThan.new(@attribute, 10)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#lteq' do
|
103
|
+
it "manufactures a less-than or equal-to predicate" do
|
104
|
+
@attribute.lteq(10).should == LessThanOrEqualTo.new(@attribute, 10)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe '#gt' do
|
109
|
+
it "manufactures a greater-than predicate" do
|
110
|
+
@attribute.gt(10).should == GreaterThan.new(@attribute, 10)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#gteq' do
|
115
|
+
it "manufactures a greater-than or equal-to predicate" do
|
116
|
+
@attribute.gteq(10).should == GreaterThanOrEqualTo.new(@attribute, 10)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#matches' do
|
121
|
+
it "manufactures a match predicate" do
|
122
|
+
@attribute.matches(/.*/).should == Match.new(@attribute, /.*/)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#in' do
|
127
|
+
it "manufactures an in predicate" do
|
128
|
+
@attribute.in(1..30).should == In.new(@attribute, (1..30))
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe Attribute::Expressions do
|
134
|
+
before do
|
135
|
+
@attribute = Attribute.new(@relation, :name)
|
136
|
+
end
|
137
|
+
|
138
|
+
describe '#count' do
|
139
|
+
it "manufactures a count Expression" do
|
140
|
+
@attribute.count.should == Count.new(@attribute)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
describe '#sum' do
|
145
|
+
it "manufactures a sum Expression" do
|
146
|
+
@attribute.sum.should == Sum.new(@attribute)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe '#maximum' do
|
151
|
+
it "manufactures a maximum Expression" do
|
152
|
+
@attribute.maximum.should == Maximum.new(@attribute)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe '#minimum' do
|
157
|
+
it "manufactures a minimum Expression" do
|
158
|
+
@attribute.minimum.should == Minimum.new(@attribute)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe '#average' do
|
163
|
+
it "manufactures an average Expression" do
|
164
|
+
@attribute.average.should == Average.new(@attribute)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe Attribute::Orderings do
|
170
|
+
describe '#asc' do
|
171
|
+
it 'manufactures an ascending ordering' do
|
172
|
+
@attribute.asc.should == Ascending.new(@attribute)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '#desc' do
|
177
|
+
it 'manufactures a descending ordering' do
|
178
|
+
@attribute.desc.should == Descending.new(@attribute)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Expression do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute = @relation[:id]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#inspect" do
|
11
|
+
it "returns a simple, short inspect string" do
|
12
|
+
@attribute.count.inspect.should == "<Arel::Count <Attribute id>>"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Expression::Transformations do
|
17
|
+
before do
|
18
|
+
@expression = Count.new(@attribute)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#bind' do
|
22
|
+
it "manufactures an attribute with a rebound relation and self as the ancestor" do
|
23
|
+
derived_relation = @relation.where(@relation[:id].eq(1))
|
24
|
+
@expression.bind(derived_relation).should == Count.new(@attribute.bind(derived_relation), nil, @expression)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns self if the substituting to the same relation" do
|
28
|
+
@expression.bind(@relation).should == @expression
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#as' do
|
33
|
+
it "manufactures an aliased expression" do
|
34
|
+
@expression.as(:alias).should == Expression.new(@attribute, :alias, @expression)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#to_attribute' do
|
39
|
+
it "manufactures an attribute with the expression as an ancestor" do
|
40
|
+
@expression.to_attribute(@relation).should == Attribute.new(@relation, @expression.alias, :ancestor => @expression)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Value do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '#bind' do
|
10
|
+
it "manufactures a new value whose relation is the provided relation" do
|
11
|
+
Value.new(1, @relation).bind(another_relation = Table.new(:photos)).should == Value.new(1, another_relation)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Alias do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe '==' do
|
10
|
+
it "obtains if the objects are the same" do
|
11
|
+
Alias.new(@relation).should_not == Alias.new(@relation)
|
12
|
+
(aliaz = Alias.new(@relation)).should == aliaz
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Join do
|
5
|
+
before do
|
6
|
+
@relation1 = Table.new(:users)
|
7
|
+
@relation2 = Table.new(:photos)
|
8
|
+
@predicate = @relation1[:id].eq(@relation2[:user_id])
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'hashing' do
|
12
|
+
it 'implements hash equality' do
|
13
|
+
InnerJoin.new(@relation1, @relation2, @predicate) \
|
14
|
+
.should hash_the_same_as(InnerJoin.new(@relation1, @relation2, @predicate))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#attributes' do
|
19
|
+
it 'combines the attributes of the two relations' do
|
20
|
+
join = InnerJoin.new(@relation1, @relation2, @predicate)
|
21
|
+
join.attributes.should ==
|
22
|
+
(@relation1.attributes + @relation2.attributes).collect { |a| a.bind(join) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Order do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute = @relation[:id]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "#==" do
|
11
|
+
it "returns true when the Orders are for the same attribute and direction" do
|
12
|
+
Ascending.new(@attribute).should == Ascending.new(@attribute)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns false when the Orders are for a diferent direction" do
|
16
|
+
Ascending.new(@attribute).should_not == Descending.new(@attribute)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Project do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute = @relation[:id]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#attributes' do
|
11
|
+
before do
|
12
|
+
@projection = Project.new(@relation, @attribute)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "manufactures attributes associated with the projection relation" do
|
16
|
+
@projection.attributes.should == [@attribute].collect { |a| a.bind(@projection) }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#externalizable?' do
|
21
|
+
describe 'when the projections are attributes' do
|
22
|
+
it 'returns false' do
|
23
|
+
Project.new(@relation, @attribute).should_not be_externalizable
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'when the projections include an aggregation' do
|
28
|
+
it "obtains" do
|
29
|
+
Project.new(@relation, @attribute.sum).should be_externalizable
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Relation do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute1 = @relation[:id]
|
8
|
+
@attribute2 = @relation[:name]
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '[]' do
|
12
|
+
describe 'when given an', Attribute do
|
13
|
+
it "return the attribute congruent to the provided attribute" do
|
14
|
+
@relation[@attribute1].should == @attribute1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'when given a', Symbol, String do
|
19
|
+
it "returns the attribute with the same name, if it exists" do
|
20
|
+
@relation[:id].should == @attribute1
|
21
|
+
@relation['id'].should == @attribute1
|
22
|
+
@relation[:does_not_exist].should be_nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Relation::Operable do
|
28
|
+
describe 'joins' do
|
29
|
+
before do
|
30
|
+
@predicate = @relation[:id].eq(@relation[:id])
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#join' do
|
34
|
+
describe 'when given a relation' do
|
35
|
+
it "manufactures an inner join operation between those two relations" do
|
36
|
+
@relation.join(@relation).on(@predicate). \
|
37
|
+
should == InnerJoin.new(@relation, @relation, @predicate)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "when given a string" do
|
42
|
+
it "manufactures a join operation with the string passed through" do
|
43
|
+
@relation.join(arbitrary_string = "ASDF").should == StringJoin.new(@relation, arbitrary_string)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "when given something blank" do
|
48
|
+
it "returns self" do
|
49
|
+
@relation.join.should == @relation
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe '#outer_join' do
|
55
|
+
it "manufactures a left outer join operation between those two relations" do
|
56
|
+
@relation.outer_join(@relation).on(@predicate). \
|
57
|
+
should == OuterJoin.new(@relation, @relation, @predicate)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#project' do
|
63
|
+
it "manufactures a projection relation" do
|
64
|
+
@relation.project(@attribute1, @attribute2). \
|
65
|
+
should == Project.new(@relation, @attribute1, @attribute2)
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "when given blank attributes" do
|
69
|
+
it "returns self" do
|
70
|
+
@relation.project.should == @relation
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#alias' do
|
76
|
+
it "manufactures an alias relation" do
|
77
|
+
@relation.alias.relation.should == Alias.new(@relation).relation
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '#where' do
|
82
|
+
before do
|
83
|
+
@predicate = Equality.new(@attribute1, @attribute2)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "manufactures a where relation" do
|
87
|
+
@relation.where(@predicate).should == Where.new(@relation, @predicate)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "accepts arbitrary strings" do
|
91
|
+
@relation.where("arbitrary").should == Where.new(@relation, "arbitrary")
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'when given a blank predicate' do
|
95
|
+
it 'returns self' do
|
96
|
+
@relation.where.should == @relation
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#order' do
|
102
|
+
it "manufactures an order relation" do
|
103
|
+
@relation.order(@attribute1, @attribute2).should == Order.new(@relation, @attribute1, @attribute2)
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'when given a blank ordering' do
|
107
|
+
it 'returns self' do
|
108
|
+
@relation.order.should == @relation
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '#take' do
|
114
|
+
it "manufactures a take relation" do
|
115
|
+
@relation.take(5).should == Take.new(@relation, 5)
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'when given a blank number of items' do
|
119
|
+
it 'returns self' do
|
120
|
+
@relation.take.should == @relation
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#skip' do
|
126
|
+
it "manufactures a skip relation" do
|
127
|
+
@relation.skip(4).should == Skip.new(@relation, 4)
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'when given a blank number of items' do
|
131
|
+
it 'returns self' do
|
132
|
+
@relation.skip.should == @relation
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '#group' do
|
138
|
+
it 'manufactures a group relation' do
|
139
|
+
@relation.group(@attribute1, @attribute2).should == Group.new(@relation, @attribute1, @attribute2)
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'when given blank groupings' do
|
143
|
+
it 'returns self' do
|
144
|
+
@relation.group.should == @relation
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe Relation::Operable::Writable do
|
150
|
+
describe '#delete' do
|
151
|
+
it 'manufactures a deletion relation' do
|
152
|
+
Session.start do
|
153
|
+
mock(Session.new).delete(Deletion.new(@relation))
|
154
|
+
@relation.delete
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe '#insert' do
|
160
|
+
it 'manufactures an insertion relation' do
|
161
|
+
Session.start do
|
162
|
+
record = { @relation[:name] => 'carl' }
|
163
|
+
mock(Session.new).create(Insert.new(@relation, record))
|
164
|
+
@relation.insert(record)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe '#update' do
|
170
|
+
it 'manufactures an update relation' do
|
171
|
+
Session.start do
|
172
|
+
assignments = { @relation[:name] => Value.new('bob', @relation) }
|
173
|
+
mock(Session.new).update(Update.new(@relation, assignments))
|
174
|
+
@relation.update(assignments)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe Relation::Enumerable do
|
182
|
+
it "implements enumerable" do
|
183
|
+
@relation.collect.should == @relation.session.read(@relation).collect
|
184
|
+
@relation.first.should == @relation.session.read(@relation).first
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|