-
Notifications
You must be signed in to change notification settings - Fork 0
/
map_test.go
140 lines (133 loc) · 3.97 KB
/
map_test.go
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package rel
import (
"fmt"
"testing"
)
// tests for map op
func TestMap(t *testing.T) {
// test the degrees, cardinality, and string representation
doubleQty := func(tup1 orderTup) orderTup {
return orderTup{tup1.PNO, tup1.SNO, tup1.Qty * 2}
}
mapKeys := [][]string{
[]string{"PNO", "SNO"},
}
rel := orders().Map(doubleQty, mapKeys)
type distinctTup struct {
PNO int
SNO int
}
type nonDistinctTup struct {
PNO int
Qty int
}
type titleCaseTup struct {
Pno int
Sno int
Qty int
}
type joinTup struct {
PNO int
SNO int
Qty int
SName string
Status int
City string
}
type groupByTup struct {
PNO int
Qty int
}
type valTup struct {
Qty int
}
groupFcn := func(val <-chan valTup) valTup {
res := valTup{}
for vi := range val {
res.Qty += vi.Qty
}
return res
}
type mapRes struct {
PNO int
SNO int
Qty1 int
Qty2 int
}
mapFcn := func(tup1 orderTup) mapRes {
return mapRes{tup1.PNO, tup1.SNO, tup1.Qty, tup1.Qty * 2}
}
var relTest = []struct {
rel Relation
expectString string
expectDeg int
expectCard int
}{
{rel, "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty})", 3, 12},
{rel.Restrict(Attribute("PNO").EQ(1)), "σ{PNO == 1}(Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}))", 3, 6},
{rel.Project(distinctTup{}), "π{PNO, SNO}(Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}))", 2, 12},
{rel.Project(nonDistinctTup{}), "π{PNO, Qty}(Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}))", 2, 10},
{rel.Rename(titleCaseTup{}), "ρ{Pno, Sno, Qty}/{PNO, SNO, Qty}(Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}))", 3, 12},
{rel.Diff(orders()), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}) − Relation(PNO, SNO, Qty)", 3, 12},
{rel.Union(orders()), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}) ∪ Relation(PNO, SNO, Qty)", 3, 24},
{rel.Join(suppliers(), joinTup{}), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}) ⋈ Relation(SNO, SName, Status, City)", 6, 11},
{rel.GroupBy(groupByTup{}, groupFcn), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}).GroupBy({PNO, Qty}->{Qty})", 2, 4},
{rel.Map(mapFcn, mapKeys), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}).Map({PNO, SNO, Qty}->{PNO, SNO, Qty1, Qty2})", 4, 12},
{rel.Map(mapFcn, [][]string{}), "Relation(PNO, SNO, Qty).Map({PNO, SNO, Qty}->{PNO, SNO, Qty}).Map({PNO, SNO, Qty}->{PNO, SNO, Qty1, Qty2})", 4, 12},
}
for i, tt := range relTest {
if err := tt.rel.Err(); err != nil {
t.Errorf("%d has Err() => %s", i, err.Error())
continue
}
if str := tt.rel.String(); str != tt.expectString {
t.Errorf("%d has String() => %v, want %v", i, str, tt.expectString)
}
if deg := Deg(tt.rel); deg != tt.expectDeg {
t.Errorf("%d %s has Deg() => %v, want %v", i, tt.expectString, deg, tt.expectDeg)
}
if card := Card(tt.rel); card != tt.expectCard {
t.Errorf("%d %s has Card() => %v, want %v", i, tt.expectString, card, tt.expectCard)
}
}
// test cancellation
res := make(chan orderTup)
cancel := rel.TupleChan(res)
close(cancel)
select {
case <-res:
t.Errorf("cancel did not end tuple generation")
default:
// passed test
}
// test errors
err := fmt.Errorf("testing error")
r1 := orders().Map(doubleQty, mapKeys).(*mapExpr)
r1.err = err
r2 := orders().Map(doubleQty, mapKeys).(*mapExpr)
r2.err = err
res = make(chan orderTup)
_ = r1.TupleChan(res)
if _, ok := <-res; ok {
t.Errorf("map did not short circuit TupleChan")
}
errTest := []Relation{
r1.Project(distinctTup{}),
r1.Restrict(Not(Attribute("PNO").EQ(1))),
r1.Rename(titleCaseTup{}),
r1.Union(r2),
rel.Union(r2),
r1.Diff(r2),
rel.Diff(r2),
r1.Join(r2, orderTup{}),
rel.Join(r2, orderTup{}),
r1.GroupBy(groupByTup{}, groupFcn),
r1.Map(mapFcn, mapKeys),
}
for i, errRel := range errTest {
if errRel.Err() != err {
t.Errorf("%d did not short circuit error", i)
}
}
}
// TODO(jonlawlor): benchmarks!