-
Notifications
You must be signed in to change notification settings - Fork 1
/
setops_spec.rb
105 lines (95 loc) · 3.08 KB
/
setops_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
CONNECTION = {
adapter: 'sqlite3',
database: File.join(__dir__, '../spec.db')
}.freeze
RecordAttrs = { name: String, dob: Date, department: String }
class TestRecord < ActiveRecord::Base
establish_connection(CONNECTION)
self.abstract_class = true
def self.generate
new(RecordAttrs.generate)
end
end
class Student < TestRecord; end
class Employee < TestRecord; end
RSpec.describe ActiveRecord::Setops do
include Gen::Test
context 'union' do
it 'should have the same cardinatilty as the two relations combined' do
for_all (30..50), (10..70) do |n, m|
TestRecord.transaction do
n.times { Student.generate.save! }
m.times { Employee.generate.save! }
end
expect((Student.all | Employee.all).count).to eq(Student.count + Employee.count)
TestRecord.transaction do
Student.delete_all
Employee.delete_all
end
end
end
end
context 'union_all' do
it 'should have the same cardinatilty as the two relations combined' do
for_all (30..50), (10..70) do |n, m|
TestRecord.transaction do
n.times { Student.generate.save! }
m.times { Employee.generate.save! }
end
expect((Student.all + Employee.all).count).to eq(Student.count + Employee.count)
TestRecord.transaction do
Student.delete_all
Employee.delete_all
end
end
end
end
context 'intersect' do
it 'should only include those records that are common' do
for_all C::ArrayOf[RecordAttrs] do |attrs|
TestRecord.transaction do
n = Student.create!(attrs).count
m = Employee.create!(attrs).count
expect(n).to eq(m)
end
num_studs = Student.count
num_emps = Employee.count
expect(num_studs).to eq(num_emps)
for_all C::ArrayOf[RecordAttrs] do |stud_attrs|
Student.create!(stud_attrs)
num_intersect = (Student.select(:name) & Employee.select(:name)).count
expect(num_intersect).to eq(num_studs)
end
for_all C::ArrayOf[RecordAttrs] do |stud_attrs|
Employee.create!(stud_attrs)
num_intersect = (Student.select(:name) & Employee.select(:name)).count
expect(num_intersect).to eq(num_emps)
end
TestRecord.transaction do
Student.delete_all
Employee.delete_all
end
end
end
end
context 'difference' do
it 'should only include those records that are not in the other' do
for_all C::ArrayOf[RecordAttrs] do |attrs|
Student.create!(attrs)
Employee.create!(attrs)
num_studs = Student.count
num_emps = Employee.count
expect(num_studs).to eq(num_emps)
for_all C::ArrayOf[RecordAttrs] do |stud_attrs|
Student.create!(stud_attrs)
num_except = (Student.select(:name) - Employee.select(:name)).count
expect(num_except).to eq(Student.count - num_emps)
end
TestRecord.transaction do
Student.delete_all
Employee.delete_all
end
end
end
end
end